求教一个问题:SERVER端接受客户端的连接。有一种情况是每个客户端的任务不同,所以设计了多个CClientObject类,比如:CClientObject1,CClientObject2~~~对接入的CLIENT如何设计,根据需求实例化不同的一个客户端类对象?大概的思路应该如何实施?SOCKETsClient=::accept();//todo…针对不同的需求,实例化一个客户端类对象。其实,就是不同客户端的业务逻辑有所不同。底层的socket通信当然没区别。如何实现不同的客户端不同的业务逻辑?
设计模式-工厂方法模式,设计模式工厂模式
场景描述:
假设现在有一个User类(如下),原本设计程序使用SqlServer访问,现在因为客户需求的变化,需要使用Access来访问。
public class User
{
private int id;
private string name;
public int ID
{
get { return id; }
set { id = value; }
}
public string Name
{
get { return name; }
set { name = value; }
}
}
对于这种场景,单纯的去修改访问数据库代码,把SqlServer的访问类,修改成Access的访问类,不仅会出现很多问题,因为两种数据库查询语句本身就有区别,最重要的是扩展性非常差,万一以后需要改成用MySql来访问,又是一通改。所以这里用到了工厂方法模式。
首先定义一个User对象接口
//User对象接口类
public interface IUser
{
//业务逻辑
void Insert(User user);
User GetUser(int i);
}
然后是两种数据库实现的User对象,都继承于IUser接口
//Sql数据库User对象
public class SqlUser : IUser
{
public void Insert(User user)
{
Console.WriteLine("InsertSqlUser");
}
public User GetUser(int i)
{
Console.WriteLine("SqlUserList");
return null;
}
}
//Access数据库User对象
public class AccessUser : IUser
{
public void Insert(User user)
{
Console.WriteLine("InsertAccessUser");
}
public User GetUser(int i)
{
Console.WriteLine("AccessUserList");
return null;
}
}
定义一个工厂接口
//工厂接口
interface IFactory
{
//继承类可以根据不同的需求产生不同的User对象
IUser CreateUser();
}
具体的工厂,根据不同的需求,产生不同的User对象
//Sql数据库工厂
public class SqlFactory : IFactory
{
//访问Sql数据库的User对象
public IUser CreateUser()
{
return new SqlUser();
}
}
//Access数据库工厂
public class AccessFactory : IFactory
{
//访问Access数据库的User对象
public IUser CreateUser()
{
return new AccessUser();
}
}
客户端实现
public static void Main(string[] args)
{
User user = new User();
//根据不同需求实例化不同数据库的工厂对象
IFactory factory = new AccessFactory();
//完成业务逻辑和数据库访问的解耦,iu对象不必知道具体产生的是哪个数据库的对象
IUser iu = factory.CreateUser();
iu.Insert(user);
iu.GetUser(1);
}
UML 类图
工厂方法模式
工厂方法模式是简单工厂模式的延伸,首先定义一个用于创建对象的接口,然后产生子类,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。
工厂方法模式实现时,客户端需要决定实例化哪一个具体工厂,也就是说,工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行,你想要加功能,本来是改工厂类的,而现在是修改客户端。
工厂方法模式的优缺点
优点:客服了简单工厂违背开放-封闭的原则,又保持了封装对象创建过程的优点。
缺点:每加增加一个产品,就要增加具体的产品工厂类,加大了开发量
本文根据《大话设计模式》整理得出
场景描述:
假设现在有一个User类(如下),原本设计程序使用SqlServer访问,现在因为客户需求…
重载工厂方法
工厂方法可能会存在多种途径来创建产品,比如日志记录系统,可以从文件中读取,也可以从数据库读取。
在抽象工厂中定义多个重载的工厂方法,在具体工厂中实现了这些工厂方法,这些方法可以包含不同的业务逻辑,以满足对不同产品对象的需求。
引入重载方法后,抽象工厂LoggerFactory的代码修改如下:
interface LoggerFactory {
public Logger createLogger();
public Logger createLogger(String args);
public Logger createLogger(Object obj);
}
总结
工厂方法模式
优化代码
demo
使用工厂模式设计日志记录器。
Logger接口充当抽象产品,其子类FileLogger和DatabaseLogger充当具体产品,LoggerFactory接口充当抽象工厂,其子类FileLoggerFactory和DatabaseLoggerFactory充当具体工厂。
//日志记录器接口:抽象产品
interface Logger {
public void writeLog();
}
//数据库日志记录器:具体产品
class DatabaseLogger implements Logger {
public void writeLog() {
System.out.println("数据库日志记录。");
}
}
//文件日志记录器:具体产品
class FileLogger implements Logger {
public void writeLog() {
System.out.println("文件日志记录。");
}
}
//日志记录器工厂接口:抽象工厂
interface LoggerFactory {
public Logger createLogger();
}
//数据库日志记录器工厂类:具体工厂
class DatabaseLoggerFactory implements LoggerFactory {
public Logger createLogger() {
//连接数据库,代码省略
//创建数据库日志记录器对象
Logger logger = new DatabaseLogger();
//初始化数据库日志记录器,代码省略
return logger;
}
}
//文件日志记录器工厂类:具体工厂
class FileLoggerFactory implements LoggerFactory {
public Logger createLogger() {
//创建文件日志记录器对象
Logger logger = new FileLogger();
//创建文件,代码省略
return logger;
}
}
客户端使用代码:
class Client {
public static void main(String args[]) {
LoggerFactory factory;
Logger logger;
factory = new FileLoggerFactory(); //可引入配置文件实现
logger = factory.createLogger();
logger.writeLog();
}
}
缺点
- 在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。
- 由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度。
相关文章
- Linux下源码包安装使用Swoole扩充),ThinkPHP使用Swoole要求安装
- 尽管是转成PCL,展开要打字与印刷的PPT
- 规划那几个定义已经被融合到C++之中,小编早先下载的多七个本子的主次都不可能通常运营
- 因为展开Keepalive功用需求消耗额外的宽带和流量,正是从未实现心跳作用
- 万一不对记录Computer进行操作,不对实施Computer举办其余操作
- 澳门新浦京8455com:本土上传还足以接纳这种措施,标签来上传文件
- 成事在人查询,两独白墙青瓦木窗格的金钱观江南民居四散随地
- json格式轻松,对json格式的字符串举行解码
- 澳门新浦京8455com但以此看似形参的花色,请在该项目中落到实处贰个力所能致得到栈最小元素的min函数
- 上风华正茂篇介绍了Mac下查尔斯的施用,图1(wireshark先楚河汉分界面)