您的位置:首页 > 编程语言 > C语言/C++

C++设计模式新解三 简单工厂 工厂模式 抽象工厂

2015-12-11 20:49 381 查看
先对比看两段代码

//水杯类,定义了一些功能
class Cup
{

};
//玻璃杯
class GlassCup : public Cup

{
};

//钢杯
class SteelCup: public Cup
{
};



下面就是重点了:

如果是 简单工厂 那么工厂的实现代码就是:

//简单工厂类
class SimpleFactory
{
public:
static Cup* CreateCup(int type)
{
Cup* result = NULL;
switch (type) //判断选择要创建对象的类型
{
case 1:
result = new GlassCup();
break;
case 2:
result = new SteelCup();
break;
}
return result;
}

};


如果是工厂

//工厂
class IFactory //定义一个接口,实现创建杯子类的功能
{
public:
virtual Cup* CreateCup() = 0;
};

class GlassFactory : public IFactory//玻璃工厂
{
public:
virtual Cup * CreateCup()
{
return new GlassCup();
}
};
class SteelFactory: public IFactory//钢铁工厂
{
public:
virtual Cup * CreateCup()
{
return new SteelCup();
}
};

int main()
{
IFactory * f1 = new GlassFactory();
Cup* c1 = f1->CreateCup();

IFactory * f2 = new SteelFactory();
Cup* c2 = f2->CreateCup();
system("Pause");
}


从上面我们可以看到,简单工厂里把继承水杯接口的真实角色的创建放在了一个工厂里,每添加一个新的真实角色,就要修改简单工厂的工厂代码。

而工厂则同样封装了真实角色的创建过程,但把不同的真实角色放在了不同的工厂里创建,每添加一个新的真实角色,新加一个继承了工厂接口的工厂类就可以了。

符合OCP原则。对修改关闭,对扩展开放。

何时使用简单工厂模式:

(这里值是使用简单工厂模式)举个更实际例子,比如你写了个应用,里面用到了数据库的封装,你的应用可以今后需要在不同的数据库环境下运行,可能是oracle,db2,sql server等,那么连接数据库的代码是不一样的,你用传统的方法,就不得不进行代码修改来适应不同的环境,非常麻烦,但是如果你采用工厂类的话,将各种可能的数据库连接全部实现在工厂类里面,通过你配置文件的修改来达到连接的是不同的数据库,那么你今后做迁移的时候代码就不用进行修改了。

Server.ini

GameWorld = 12

TryCatch = 0

InterStub = 0

InterGateway = 0

InterCache = 0

WorldServerIP = 127.0.0.1

WorldServerPort = 9401

WorldClientPort = 9402

UpdateServerIP = 127.0.0.1

UpdateServerPort = 9404

GatewayServerIP = 127.0.0.1

GatewayServerPort = 8701

GatewayClientPort = 9701

CacheServerIP = 127.0.0.1

CacheServerPort = 7701

AutoStartManagerConnect = 0

ManagerServerIP = 127.0.0.1

ManagerServerPort = 28701

FixQueue = 0

AdjustQueue=1

比如 读取到第一个GameWorld = 1 怎样处理等,相当于传的那个 which参数了。

抽象工厂模式代码:

// 水壶
class Kettle
{
}

//玻璃水壶
class GlassKettle: public Kettle
{

}

//铁水壶
class SteelKettle: public Kettle
{

}


如果那么就要在工厂接口里,

//工厂
class IFactory //定义一个接口,实现创建杯子类的功能
{
public:
virtual Cup* CreateCup() = 0;
virtual Cup* CreateKettle() = 0;
};

class GlassFactory : public IFactory//玻璃工厂
{
public:
virtual Cup * CreateCup()
{
return new GlassCup();
}
virtual Cup * CreateCup()
{
return new GlassKettle();
}
};

class SteelFactory: public IFactory//钢铁工厂
{
public:
virtual Cup * CreateCup()
{
return new SteelCup();
}
virtual Kettle * CreateKettle()
{
return new SteelKettle();

};
}


大家注意这里最重要的一点是什么,不同的工厂真实对象里有相同的原料,没错 无论是玻璃水杯,玻璃水壶,玻璃花瓶 用的原料都是玻璃。

这就是抽象工厂中不同的函数之间的耦合关系。而工厂模式则没有这种耦合关系。因为一个工厂里只生产一种产品,无所谓耦合不耦合。

大部分抽象工厂模式都是这样的:
---它的里面是一堆工厂方法,每个工厂方法返回某种类型的对象。

比如说工厂可以生产鼠标和键盘。那么抽象工厂的实现类(它的某个具体子类)的对象都可以生产鼠标和键盘,但可能工厂A生产的是罗技的键盘和鼠标,工厂B是微软的。

这样A和B就是工厂,对应于抽象工厂;
每个工厂生产的鼠标和键盘就是产品,对应于工厂方法;

用了工厂方法模式,你替换生成键盘的工厂方法,就可以把键盘从罗技换到微软。但是用了抽象工厂模式,你只要换家工厂,就可以同时替换鼠标和键盘一套。如果你要的产品有几十个,当然用抽象工厂模式一次替换全部最方便(这个工厂会替你用相应的工厂方法)

所以说抽象工厂就像工厂,而工厂方法则像是工厂的一种产品生产线
----------------

有人做如下的比较:
工厂方法模式:一个抽象产品类,可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类只能创建一个具体产品类的实例。
抽象工厂模式:多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。
一个抽象工厂类,可以派生出多个具体工厂类。
每个具体工厂类可以创建多个具体产品类的实例。
区别:工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。

工厂模式是对具体产品进行扩展,有的项目可能需要更多的扩展性,要对这个“工厂”也进行扩展,那就成了“抽象工厂模式”。

本文参考:

http://baike.baidu.com/view/1306799.htm

http://www.cnblogs.com/BeyondAnyTime/archive/2012/07/06/2579100.html

http://zhidao.baidu.com/question/56572039.html?

http://zhidao.baidu.com/link?url=gPlMaK_UQogcLh27dxuY13bK24myNbPa_5sYRluAId30Oj1wxKs_AmPRKLChhvyvWRiAkvHxOrc9DXkoZLpuDJ7UPoEP1AtTUNHzvwK0alyqbl=relate_question_0&word=%B9%A4%B3%A7%C4%A3%CA%BD%20%BC%F2%B5%A5%B9%A4%B3%A7

http://blog.csdn.net/lishuangzhe7047/article/details/8491269
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: