设计模式之建造者模式

释放双眼,带上耳机,听听看~!

设计模式之建造者模式

引入

Sunny 软件公司游戏开发小组决定开发一款网络游戏,该游戏采用RPG(Role Playing Game)模式,玩家可以在游戏中扮演虚拟世界中的一个特定角色,角色根据不同的游戏情节和统计数据(如力量、魔法、技能等)具有不同的能力,角色也会随着不断升级而拥有更强大的能力。
作为 RPG 游戏的一个重要组成部分,需要对游戏角色进行设计,而且随着该游戏的升级将不断增加新的角色。不同类型的游戏角色,其性别、脸型、服装、发型等外部特性都有所差异,

例如:

  • “天使”拥有美丽的面容和披肩的长发,并身穿一袭白裙;
  • “恶魔”极其丑陋,留着光头并穿一件刺眼的黑衣。

Sunny 公司决定开发一个小工具来创建游戏角色,可以创建不同类
型的角色并可以灵活增加新的角色。

Sunny 公司的开发人员通过分析发现,游戏角色是一个复杂对象,它包含性别、脸型等多个组成部分,不同的游戏角色其组成部分有所差异。但无论是何种造型的游戏角色,它的创建步骤都大同小异,都可以按照一定的流程逐步创建其组成部分,再将各组成部分装配成一个完整的游戏角色。
如何一步步创建一个包含多个组成部分的复杂对象,这是一个需要解决的问题。

设计模式之建造者模式

其代码如下:


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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
1using System;
2
3public class Actor {
4    public string Costume { get; set; }
5    public string Face { get; set;}
6    public string HairStyle { get; set; }
7    public string Sex { get; set;}
8    public string Type { get; set; }
9}
10
11public abstract class ActorBuilder {
12    protected Actor Actor = new Actor();
13    public abstract void BuildCostume();
14    public abstract void BuildFace();
15    public abstract void BuildHairStyle();
16    public abstract void BuildSex();
17    public abstract void BuildType();
18    public Actor CreateActor() {
19        return Actor;
20    }
21}
22public class ActorController{
23    public Actor Construct(ActorBuilder ab){
24        ab.BuildCostume();
25        ab.BuildFace();
26        ab.BuildHairStyle();
27        ab.BuildSex();
28        ab.BuildType();
29        return ab.CreateActor();
30    }
31}
32
33public class HeroActor : ActorBuilder
34{
35    public override void BuildType()
36    {
37        Actor.Type = "英雄";
38    }
39    public override void BuildSex()
40    {
41        Actor.Sex = "男";
42    }
43    public override void BuildFace()
44    {
45        Actor.Face = "英俊";
46    }
47    public override void BuildCostume()
48    {
49        Actor.Costume = "盔甲";
50    }
51    public override void BuildHairStyle()
52    {
53        Actor.HairStyle = "飘逸";
54    }
55}
56
57public class AngelBuilder : ActorBuilder {
58    public override void BuildType()
59    {
60        Actor.Type = "天使";
61    }
62    public override void BuildSex()
63    {
64        Actor.Sex = "女";
65    }
66    public override void BuildFace()
67    {
68        Actor.Face = "漂亮";
69    }
70    public override void BuildCostume()
71    {
72        Actor.Costume = "白裙";
73    }
74    public override void BuildHairStyle()
75    {
76        Actor.HairStyle = "披肩长发";
77    }
78}
79
80public class DevilBuilder : ActorBuilder {
81    public override void BuildType()
82    {
83        Actor.Type = "恶魔";
84    }
85    public override void BuildSex()
86    {
87        Actor.Sex = "妖";
88    }
89    public override void BuildFace()
90    {
91        Actor.Face = "丑陋";
92    }
93    public override void BuildCostume()
94    {
95        Actor.Costume = "黑衣";
96    }
97    public override void BuildHairStyle()
98    {
99        Actor.HairStyle = "光头";
100    }
101}
102
103
  • 符合单一职责原则
  • 符合开闭原则

建造者模式(Builder Pattern)

建造者模式:

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

不同的实体创建者可以定义不同的创建过程,而且不同的实体建造者相互独立,增加新的建造者不用修改已有代码,满足”开闭原则“。

其结构如下:

设计模式之建造者模式

  • Product 产品类:是被创建的复杂对象

  • Builder 抽象建造者类:为创建Product对象的各个部件定义抽象接口,一般有两类方法:

  • BuildPartX(),创建复杂对象的各个部件

    • GetResult(),返回复杂对象
  • ConcreteBuilder 具体建造者类:复写抽象建造者类中的方法,创建一个具体Product

  • Director 指挥者类:负责安排复杂对象的创建次序,在Director的Construct()方法中按一定顺序调回建造者类的方法,完成复杂对象的创建。

Director类的高级应用

  • 省略Director

将Builder与Director进行合并

如:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1public abstract class ActorBuilder
2{
3    protected Actor Actor = new Actor();
4    public abstract void BuildType();
5    public abstract void BuildSex();
6    public abstract void BuildFace();
7    public abstract void BuildCostume();
8    public abstract void BuildHairStyle();
9    public Actor Construct()
10    {
11        BuildCostume();
12        BuildFace();
13        BuildHairStyle();
14        BuildSex();
15        BuildType();
16        return Actor;
17    }
18}
19
20

这样简化了系统结构,但加重了抽象建造者的职责。

  • 引入钩子方法

引入钩子方法,更精细的控制产品的创建过程。

钩子方法:

返回类型通常为bool类型,定义在抽象建造者类中

例如我们可以在游戏角色的抽象建造者类ActorBuilder 中定义
一个方法IsBareHeaded() ,用于判断某个角色是否为“光头”,
默认返回值为false 。


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
1public abstract class ActorBuilder
2{
3    protected Actor Actor = new Actor();
4    public virtual bool IsBareHeaded()
5    {
6       return false;
7    }
8    public abstract void BuildType();
9    public abstract void BuildSex();
10    public abstract void BuildFace();
11    public abstract void BuildCostume();
12    public abstract void BuildHairStyle();
13    public Actor CreateActor()
14    {
15      return Actor;
16    }
17}
18
19public class ActorController
20{
21    public Actor Construct(ActorBuilder ab)
22    {
23        ab.BuildType();
24        ab.BuildSex();
25        ab.BuildFace();
26        ab.BuildCostume();
27        if (ab.IsBareHeaded() == false)
28        {
29          ab.BuildHairStyle();
30        }
31        return ab.CreateActor();
32    }
33}
34
35

抽象工厂模式与建造者模式对比

  • 抽象工厂模式返回一系列相关产品,建造者模式返回一个完整的复杂产品
  • 抽象工厂模式中,客户端通过选择具体工厂来生产具体产品;建造者模式中,客户端通过选择具体建造者,通过Director类一步步创建一个复杂对象,并返回。

给TA打赏
共{{data.count}}人
人已打赏
安全运维

docker安装mongodb

2021-12-11 11:36:11

安全运维

Ubuntu上NFS的安装配置

2021-12-19 17:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索