先读一本设计模式入门书,深入浅出设计模式,之后再拜读一下GOF设计模式。
工作也有两年时间了,说设计模式接触的应该比较多了,只是一直没有进行系统的整理。说起来,刚入职做Webkit这让我有一个比较高的技术起点,技术视界也比较宽广。抓时间系统过一遍设计模式,探究下编码的艺术。
工厂模式:为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来。好比是:工厂生产产品,只需要告诉工厂需要什么样的产品,不需关心制造产品的具体过程。
书中将工厂模式分为三类:
简单工厂模式
工厂方法模式
抽象工厂模式
1. 简单工厂模式
和名字一样很简单,由如下组成:
1. 工厂 创建“产品”对象统一通过“工厂”进行,只需要告诉工厂不同的产品需求,就会产生具体产品。不需要了解产品制造过程。
2. 抽象的产品 具体产品的父类,定义同类产品的通用特性。
3. 具体的产品 就是具体的产品
直接上代码,对程序员来说,这是最直观的解释。
enum TCarType { EBenz, EBMW }; //抽象产品 class Car { public: virtual void Drive() = NULL; }; //具体产品 class Benz : public Car { public: void Drive(){ /*benz drive method*/ } }; class BMW : public Car { public: void Drive(){ /*BMW drive method*/ } }; class CarFactory { public: static Car* ProduceCar(TCarType atype) { switch (atype) { case EBenz : return new Benz(); case EBMW : return new BMW(); default : return NULL; } } };
这种模式,并不符合开闭原则,如果新增汽车类型,那么需要修改CarFactory中静态函数的switch代码。
2. 工厂方法模式
工厂方法模式去掉简单工厂模式中,工厂方法的静态属性,使可以被子类继承。它的组成如下:
1. 抽象工厂
2. 具体工厂
3. 抽象产品
4. 具体产品
抽象产品和具体产品的代码不需要修改,下面没有列出,以下是抽象工厂和具体工厂的实现。
class CarFactory { public: virtual Car* ProduceCar(/*TCarType atype*/) = NULL; }; class BenzFactory { public: Car* ProduceCar(/*TCarType atype*/) { return new Benz(); } }; class BMWFactory { public: Car* ProduceCar(/*TCarType atype*/) { return new BMW(); } }; //简单调用方法 CarFactory* facory = new BMWFactory(); Car* bmw = facory->ProduceCar();
可以看到,由于加入抽象工厂,对象的数量成倍增长,每个产品都需要对应一个工厂。当然,我们可以通过传入atype参数,将一类汽车放入一个工厂中生产。
3. 抽象工厂模式
我觉得这个和工厂方法模式区别不大,就是对工厂和产品做了一个分类。
//抽象产品 class NewCar { public: virtual void DriveNew() = NULL; }; class OldCar { public: virtual void DriveOld() = NULL; }; //具体产品 class BenzNew : public NewCar { public: void Drive(){ /*benz drive method*/ } }; class BenzOld : public OldCar { public: void Drive(){ /*benz drive method*/ } }; class BMWNew : public NewCar { public: void Drive(){ /*BMW drive method*/ } }; class BMWOld : public OldCar { public: void Drive(){ /*BMW drive method*/ } }; //工厂 class CarFactory { public: virtual NewCar* ProduceNewCar(/*TCarType atype*/) = NULL; virtual OldCar* ProduceOldCar(/*TCarType atype*/) = NULL; }; class BenzFactory : public CarFactory { public: NewCar* ProduceNewCar(/*TCarType atype*/) { return new BenzNew(); } OldCar* ProduceOldCar(/*TCarType atype*/) { return new BenzOld(); } }; class BMWFactory : public CarFactory { public: NewCar* ProduceNewCar(/*TCarType atype*/) { return new BMWNew(); } OldCar* ProduceOldCar(/*TCarType atype*/) { return new BMWOld(); } }; //简单调用方法 CarFactory* factory = new BenzFactory(); NewCar* newCar = factory->ProduceNewCar(); OldCar* oldCar = factory->ProduceOldCar();