先读一本设计模式入门书,深入浅出设计模式,之后再拜读一下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();