本文是我学习刘伟技术博客的笔记,博客链接如下:
结构图的伪代码如下:
http://blog.csdn.net/lovelion/article/details/17517213
我做的这部分笔记,鉴于自身水平有限,我只是对上面博客内做进一步提炼和记录,方便自己查阅。同时,更多的是对设计模式的框架进行学习,大部分细节都将略去,让自己侧重对每个设计模式框架的理解。
我应该理解和掌握的:
1)能够画出这个设计模式的架构框图;
2)能够根据架构框图写出对应的伪代码;
3)这个模式的应用场景,主要优缺点。
1.简单工厂
(1)定义
简单工厂不属于GoF 23个经典设计模式,这里为了引入工厂方法,抽象工厂做准备。
简单工厂模式定义:给定一个工厂类,它将根据传进来的不同参数返回不同类的实例,被创建的实例通常有共同的父类。简单工厂模式中用于创建实例的方法是静态方法,故又称静态工厂方法。
下面是结构图,具体代码将不再贴出,由框架自己在联想代码怎么设计以及每个类的作用:
enum ProductId
{
PRODUCTA,
PRODUCTB,
MAX,
};
class product //抽象产品类
{
public:
virtual void display();
};
class ConcreteProductA:public product //具体产品类A
{
public:
void display();
};
void ConcreteProductA::display()
{
log("display ConcreteProductA");
}
class ConcreteProductB:public priduct //具体产品类B
{
public:
void display();
};
void ConcreteProductB::display()
{
log("display ConcreteProductB");
}
class Factory //抽象工厂类
{
public:
virtual product* Create(ProductId id);
};
class ConcreteFactory:public Factory //具体工厂类
{
public:
product* Create(ProductId id);
};
product* ConcreteFactory::Create(ProductId id)
{
if(id == PRODUCTA)
{
return new ConcreteProductA();
}
else if(id == PRODUCTB)
{
return new ConcreteProductB();
}
else
{
...
}
}
//客户端如下
int main()
{
Product pd = NULL;
pd = ConcreteFactory.Create(PRODUCTB);//创建ConcreteProductB
pd.display();
return 0;
}
(2)总结
1)工厂类包含必要的逻辑判断,同时也表明承担的职责过重,违反单一原则;
2)系统扩展困难,一旦添加产品必须修改工厂类的逻辑,不利于扩展和维护。
(3)适用场景
1)工厂类负责创建的对象比较少;
2)客户端只知道传入工厂类的参数,不关心如何创建。
2.工厂方法
在简单工厂模式中,如要要增加一个产品类,则需要修改工厂类的创建方法,违背了开闭原则。在工厂方法中,不再提供一个统一的工厂类来创建所有的产品对象,针对不同的产品提供不同的工厂,系统提供一个与产品等级结构对应的工厂等级结构。
(1)定义
工厂方法:定义一个用于创建产品的接口或基类,让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。工厂方法又称工厂模式。
它的结构图如下:
1)Product:定义工厂方法所创建的对象的接口;
2)ConcreteProduct:实现Product接口;
3)Fractory:声明工厂方法,返回一个Product类型对象;
4)ConcreteFactory:重定义工厂方法以返回一个ConcreteProduct对象。
以上架构框结构图的伪代码如下,Product部分和简单工厂代码一样:
class Factory //抽象工厂类
{
public:
virtual product* Create();
};
class ConcreteFactoryA:public Factory //具体工厂类A
{
public:
product* Create();
};
product* ConcreteFactoryA::Create()
{
return new ConcreteProductA();
}
class ConcreteFactoryB:public Factory //具体工厂类B
{
public:
product* Create();
};
product* ConcreteFactoryB::Create()
{
return new ConcreteProductB();
}
//客户端如下
int main()
{
Product pdA = NULL;
pdA = ConcreteFactoryA.Create();//创建ConcreteProductA
pdA.display();
Product pdB = NULL;
pdB = ConcreteFactoryB.Create();//创建ConcreteProductB
pdB.display();
return 0;
}
下面再来看一个工厂方法的隐藏,客户端无需调用工厂方法创建产品,直接通过工厂既可以使用所创建的对象中的业务方法:
结构图的伪代码如下,Product部分和简单工厂代码一样:
class Factory //抽象工厂类
{
public:
virtual product* Create();
void display(); //product 方法
};
void Factory::display() //product 方法
{
Product pd = this.Create(); //由子类创建
pd.display();
}
class ConcreteFactoryA:public Factory //具体工厂类A
{
public:
product* Create();
};
product* ConcreteFactoryA::Create()
{
return new ConcreteProductA();
}
class ConcreteFactoryB:public Factory //具体工厂类B
{
public:
product* Create();
};
product* ConcreteFactoryB::Create()
{
return new ConcreteProductB();
}
(2)总结
1)工厂方法是简单工厂的延伸,继承了他的优点,是使用频率最高的设计模式之一;
2)基于工厂角色和产品角色的多态性设计是关键;
3)新加入产品,无需更改原有代码,只需添加一个对应的具体工厂和具体产品就可以;
4)扩展需要同时加入具体工厂和具体产品,类个数将成对增加,会增加系统的复杂性。
(3)适用场景
1)客户端不知道他所需要的具体产品对象的类,只需要知道所对应的工厂即可;
2)当一个类希望由他的子类来指定它所创建的对象的时候;
3)抽象工厂类提供创建产品的接口,通过其子类来指定创建哪个对象,利用面向对象的多态性和里氏代换原则,在程序运行时,子类对象将覆盖父类对象,从而使得系统更容易扩展。