创建型模式

Last updated on 8 months ago

23种模式中可以划分为三大类,分别是 创建型模式,结构型模式,行为模式,这三部分我分三篇来写,本文主要介绍创建型模式

什么事创建型模式?

创建型模式提供了创建对象的机制,能够提升已有代码的灵活性和可复用性。

创建模式分为几种?

  • 工厂方法
  • 抽象方法
  • 生成器
  • 原型
  • 单例

工厂方法

假如说有个工厂,这个工厂专门生产球类,每次客户都发订单给这个工厂,工厂根据不同订单做好球并发给客户,客户只需知道他需要什么球,不需要知道这其中球是怎么做出来的;这就是工厂模式的通俗的解释,我需要创建一个类,不是直接new,而是由一个工厂对象决定创建出哪一种产品类的实例,简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类,这个产品类怎么new 出来的则不需要调用者关心。

一下是 工厂类demon,根据不同的输入,new出不同的交通工具

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

namespace Factory_methon {
class ProductBall {
public:
virtual ~ProductBall(){};
virtual void whatBall() = 0;
};
class ProductBasketball : public ProductBall {
public:
void whatBall() { std::cout << "I am Basketball" << std::endl; }
};
class ProductFootball : public ProductBall {
public:
void whatBall() { std::cout << "I am Football" << std::endl; }
};

class Facoty {
public:
ProductBall *createTransport(int i) {
std::cout << "creat!!!" << std::endl;
switch (i) {
case Foot:
return new ProductFootball();
case Basketball:
return new ProductBasketball();
default:
break;
}
}
};
};

优点:

  • 你可以避免创建者和具体产品之间的紧密耦合
  • 单一职责原则。你可以将产品创建代码放在程序的单一位置,从而使得代码更容易维护。
  • 开闭原则。无需更改现有客户端代码,你就可以在程序中引入新的产品类型。

缺点:

  • 应用工厂方法模式需要引入许多新的子类,代码可能会因此变得更复杂臃肿。

抽象工厂

它能创建一系列相关的对象,而无需指定其具体类。抽象工厂可以帮助减少系统的工厂数量的,但前提条件就是这些工厂要具备两个及以上的共性

方法工厂中,根据想要的球类生成球,现在多一个条件,即球有分为不同生产地,原本生产篮球没有指定产地,现在篮球又分为国产和进口的(还有很多个产地),其他的球也如此,这样一来需要添加很多的工厂类,针对这种情况可以进行分类,生成篮球的作为单独一个工厂,这个工厂里又可以生成出来自不同产地的篮球~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
namespace Factory_Abstract {

// 不同篮球产地
class AbsProBasketball {
public:
virtual ~AbsProBasketball(){};
virtual std::string whatball() const = 0;
};

class Basketball_USA : public AbsProBasketball {
public:
std::string whatball() const override {
std::cout << "i am Basketball_USA" << std::endl;
}
};

class Basketball_CHINA : public AbsProBasketball {
public:
std::string whatball() const override {
std::cout << "i am Basketball_CHINA" << std::endl;
}
};

// 不同足球产地
class AbsProFootball {
public:
virtual ~AbsProFootball(){};
virtual std::string whatball() const = 0;
};

class Football_USA : public AbsProFootball {
public:
std::string whatball() const override {
std::cout << "i am Football_USA" << std::endl;
}
};

class Football_CHINA : public AbsProFootball {
public:
std::string whatball() const override {
std::cout << "i am Football_CHINA" << std::endl;
}
};

//工厂类 ,有两个纯虚函数需要实现
//分别是生产篮球和足球的
class AbstractFactory {
public:
virtual AbsProFootball *CreateProductFootball() const = 0;
virtual AbsProBasketball *CreateProductBasktball() const = 0;
};

//这里根据不同厂地划分 美国生成的
class ConcreteFactoryBY_USA : public AbstractFactory {
public:
AbsProFootball *CreateProductFootball() const override {
return new Football_USA();
}
AbsProBasketball *CreateProductBasktball() const override {
return new Basketball_USA();
}
};

//中国生产的
class ConcreteFactoryBY_CHINA : public AbstractFactory {
public:
AbsProFootball *CreateProductFootball() const override {
return new Football_CHINA();
}
AbsProBasketball *CreateProductBasktball() const override {
return new Basketball_CHINA();
}
};

}

优点:

  • 避免客户端和具体产品代码的耦合。
  • 单一职责原则。你可以将产品生成代码抽取到同一位置,使得代码易于维护
  • 开闭原则。向应用程序中引入新产品变体时,你无需修改客户端代码。

缺点

  • 由于采用该模式需要向应用中引入众多接口和类,代码可能会比之前更加复杂。

生成器

假如你要建一个房子,房子构造本身就很复杂,你需要门,屋顶,窗户,家居等等…这些事是必须的,有些人需要只要一个厕所,有些人又不用,既然这样,那就你来组装,只需要说出你的对房子的基本要求(前提是我有),把这些门,屋顶..都细分开来,供客户选择;创建的顺序都可以由客户定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/ 构建 接口
class Builder {
public:
virtual ~Builder(){};
virtual void ProduceWall() const = 0;
virtual void ProduceDoor() const = 0;
virtual void ProduceWindow() const = 0;
virtual void ProduceRestroom() const = 0;
};
//实现 房子组件的接口
class BUilderHouse : public Builder {
private:
/* data */
public:
House_A *house;
void Rest() { this->house = new House_A(); }

void ProduceWall() const override {
house->part_of_housr_by_order.push_back(" Creat Wall ");
}

void ProduceDoor() const override {
house->part_of_housr_by_order.push_back(" Creat Door ");
}

void ProduceWindow() const override {
house->part_of_housr_by_order.push_back(" Creat Window");
}

void ProduceRestroom() const override {
house->part_of_housr_by_order.push_back(" Creat RestRoom");
}
House_A *getHouse() { return this->house; }
BUilderHouse(/* args */) { this->Rest(); };

~BUilderHouse();
};

//用一个构建类生成房子
// 按照指定的顺序构建
class Builder_by_order {

private:
Builder *builder;

public:
void init_builder(Builder *builder) { this->builder = builder; }
void BuilderHouseA1() {
this->builder->ProduceRestroom();
this->builder->ProduceWall();
this->builder->ProduceWindow();
}
};

void ClienCode(Builder_by_order &Builder) {
BUilderHouse *Houser = new BUilderHouse();
Builder.init_builder(Houser);
Builder.BuilderHouseA1();
House_A *H = Houser->getHouse();
H->ListHouse();
}

};

优点:

  • 你可以分步创建对象,暂缓创建步骤或递归运行创建步骤。

  • 生成不同形式的产品时,你可以复用相同的制造代码。

  • 单一职责原则。你可以将复杂构造代码从产品的业务逻辑中分离出来。

缺点:

  • 由于该模式需要新增多个类,因此代码整体复杂程度会有所增加。