设计模式-05-建造者模式

设计模式-05-建造者模式

个人github地址:HibisciDai

设计模式系列项目源码:HibisciDai/DesignPattern-LearningNotes-HibisciDai

processon在线UML类图:processon

[TOC]

设计模式-05-建造者模式

建造者模式(Builder Pattern)

意图

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

主要解决

主要解决在软件系统中,有时候面临着”一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。

何时使用

一些基本部件不会变,而其组合经常变化的时候。

关键代码

建造者:创建和提供实例。
导演:管理建造出来的实例的依赖关系。

如何解决

将变与不变分离开。

应用实例

  • 去肯德基,汉堡、可乐、薯条、炸鸡翅等是不变的,而其组合是经常变化的,生成出所谓的”套餐”。
  • JAVA 中的 StringBuilder。

优点

当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。

缺点

  • 建造者独立,易扩展。
  • 便于控制细节风险。

注意事项

与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。

案例1

杯子构造过程。

类图

代码

pattern05.bulider.demo1

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
public class Director {
void create(MyBulider b) {
b.BuliderString();
b.BuliderCup();
b.BuliderBody();
b.getResult();
}
}

public abstract class MyBulider {
String myString;
String myCup;
String myBody;

abstract void BuliderString();

abstract void BuliderCup();

abstract void BuliderBody();

void getResult() {
System.out.println(myString);
System.out.println(myCup);
System.out.println(myBody);
}
}

public class GlassCupBulider extends MyBulider {

@Override
void BuliderString() {
this.myString = "GlassCup-String";
}

@Override
void BuliderCup() {
this.myCup = "GlassCup-Cup";
}

@Override
void BuliderBody() {
this.myBody = "GlassCup-Body";
}
}

public class SportCupBulider extends MyBulider {

@Override
void BuliderString() {
this.myString = "SportCup-String";
}

@Override
void BuliderCup() {
this.myCup = "SportCup-Cup";
}

@Override
void BuliderBody() {
this.myBody = "SportCup-Body";
}
}

目标对象:

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
public class Cup {
String CupString;
String Cup;
String CupBody;

public String getCupString() {
return CupString;
}

public void setCupString(String cupString) {
CupString = cupString;
}

public String getCup() {
return Cup;
}

public void setCup(String cup) {
Cup = cup;
}

public String getCupBody() {
return CupBody;
}

public void setCupBody(String cupBody) {
CupBody = cupBody;
}

void drink() {
System.out.println(CupString + Cup + CupBody);
}
}

测试输出

1
2
3
4
5
6
7
8
9
10
11
public class Main {
public static void main(String[] args) {
Director d1 = new Director();
MyBulider mb1 = new SportCupBulider();
d1.create(mb1);

Director d2 = new Director();
MyBulider mb2 = new GlassCupBulider();
d2.create(mb2);
}
}
1
2
3
4
5
6
SportCup-String
SportCup-Cup
SportCup-Body
GlassCup-String
GlassCup-Cup
GlassCup-Body

案例2

对话框构建过程。

类图

代码

pattern05.bulider.demo2

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
public abstract class MyBulider {
String title;
String icon;
String message;

abstract void BuliderTitle();

abstract void BuliderIcon();

abstract void BuliderMessage();

void getResult() {
System.out.println(title);
System.out.println(icon);
System.out.println(message);
}
}

public class Conform extends MyBulider {

@Override
void BuliderTitle() {
title = "Conform-title";
}

@Override
void BuliderIcon() {
icon = "Conform-icon";
}

@Override
void BuliderMessage() {
message = "Conform-message";
}
}

public class Information extends MyBulider {

@Override
void BuliderTitle() {
title = "Information-title";
}

@Override
void BuliderIcon() {
icon = "Information-icon";
}

@Override
void BuliderMessage() {
message = "Information-message";
}
}

public class Director {
MyBulider mb;

Director(MyBulider mb) {
this.mb = mb;
}

void create() {
mb.BuliderIcon();
mb.BuliderMessage();
mb.BuliderTitle();
mb.getResult();
}
}

构建对象

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
public class Diolog {
String title;
String icon;
String message;

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public String getIcon() {
return icon;
}

public void setIcon(String icon) {
this.icon = icon;
}

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}
}

测试输出

1
2
3
4
5
6
7
8
9
10
11
public class Main {
public static void main(String[] args) {
MyBulider mb1 = new Conform();
Director d1 = new Director(mb1);
d1.create();

MyBulider mb2 = new Information();
Director d2 = new Director(mb2);
d2.create();
}
}
1
2
3
4
5
6
Conform-title
Conform-icon
Conform-message
Information-title
Information-icon
Information-message

补充

  1. Bulider限定名在java中有指定类,代码例中更改为MyBulider

  2. 对于Builder中引用指定对象需要打破封装,即透视目标构建配件的结构,并声明为自己的成员变量,即目标对象与建造者有相同的成员变量。

  3. 关于两个案例中Director类构造有些不同导致方法调用有不一样。

案例一

1
2
3
4
5
6
7
8
public class Director {
void create(MyBulider b) {
b.BuliderString();
b.BuliderCup();
b.BuliderBody();
b.getResult();
}
}

案例二

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Director {
MyBulider mb;

Director(MyBulider mb) {
this.mb = mb;
}

void create() {
mb.BuliderIcon();
mb.BuliderMessage();
mb.BuliderTitle();
mb.getResult();
}
}
文章作者: HibisciDai
文章链接: http://hibiscidai.com/2018/03/28/设计模式-05-建造者模式/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 HibisciDai
好用、实惠、稳定的梯子,点击这里