设计模式之创建型模式
Factory Method
关于工厂模式的一个比较好的介绍:工厂设计模式有什么用? - 郭小成的回答 - 知乎
解决了硬编码
一个类如果发生了变动,假使你使用了硬编码(直接new),那么你还得找到所有new的地方一个一个更改
而将new的过程放入Factory中,那么你只用改变Factory就行了
Abstract Factory
抽象工厂模式提供了一种方式,可以将一组具有同一主题的单独的工厂封装起来(如果不把同一主题的封装起来,而是一味使用Factory Method,代码量会急剧膨胀)
在正常使用中,客户端程序需要创建抽象工厂的具体实现,然后使用抽象工厂作为接口来创建这一主题的具体对象
不同的theme
,控件的观感也不同
我们可以定义一个ThemeFactory
作为base class(interface)
然后通过继承(实现)衍生出各种(derived)class
以此来实现不同的theme
每一种theme
都有不同风格的widget
,我们将其称之为factory
的product
1 | class ThemeFactory { |
然后关于Abstract Factory
优点是
- 分离了具体的类
- 使得便于交换产品的系列(通过创建不同的
derived class
) - 它有利于产品的一致性(每一个
derived class
所产出的产品都是一一致的)
缺点是
- 难以加入新种类的产品(当
base class
加入新产品时,derived class
的也要加入新的产品,这就要修改大量的derived class
)
1 |
|
Builder
Builder模式由Director和Builder组成
虽然名为Builder,但是Director才是重点
将一个复杂对象的构建和它的表示分离,使得同样的创建过程可有不同的表示
效果:
- 可以改变一个产品的内部表示
- 将构建代码和表示代码分开
- 可以对构建过程有更加精细的控制
相对于Abstract Factory,Builder重视的是一个构建的过程(direct),而Abstract Factory只是提供零件的过程
可以这么认为,Abstract Facotry套上Builder模式也可以产生一个新的Builder( director + builder )
想构建不同的产品?新增builder就好
1 |
|
Prototype
通过原型实例指定对象种类,并且通过拷贝这些原型创建新的对象
原型模式是创建型模式的一种,其特点在于通过“复制”一个已经存在的实例来返回新的实例,而不是新建实例。被复制的实例就是我们所称的“原型”,这个原型是可定制的。
原型模式多用于创建复杂的或者耗时的实例,因为这种情况下,复制一个已经存在的实例使程序运行更高效;或者创建值相等,只是命名不一样的同类数据。
Prototype模式的核心就是,复制整体,修改部分,形成一个新的实例
举个不是特别恰当的例子
例如Jack需要多份简历,简历大部分都是相同的,只有工作经验不同
因此,只需要复制一份之前的简历,再修改一下工作经验即可
例如1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18class Resume {
private:
std::string Name;
int Age;
std::string Experience;
public:
Resume(std::string name, int age, std::string experience);
Resume * Clone() {return new Resume(*this);};
void SetPersonalInfo();
void SetExperience(std::string expr);
};
int main() {
Resume *resume1 = new Resume("Jack", 26, "Work on A Company");
Resume *resume2 = resume1->Clone();
resume2->SetExperience("Work on B Company")
return 0;
}
可能这个例子不是特别能说明原型模式的好处,但是如果在构造时需要设置多个属性(例如20个)
但是大部分属性都是相同,只需要修改部分属性,那么原型模式的好处就会大大体现出来
SingleTon
保证一个类只有一个实例,并提供一个访问它的全局访问点
对于一些类来说,只有一个实例是很重要的
例如:打印机,数据库等
SingleTon的效果是
- 对唯一实例的受控访问
- 缩小名空间,放置全局变量污染
- 允许对操作和表示的精化
- 允许可变数目的实例
- 比类操作更灵活
实现:
如何保证一个唯一的实例?
可以将创建实例的操作放在一个类操作后面
例如1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16class Singleton {
private:
static Singleton* _instance;
protected:
Singleton(){};
public:
static Singleton * Instance();
};
Singleton * Singleton::_instance = nullptr;
Singleton * Singleton::Instance(){
if (!_instance)
_instance = new Singleton;
return _instance;
}