【注意】最后更新于 December 19, 2017,文中内容可能已过时,请谨慎使用。
这篇来说一说java设计模式之builder模式
builder,就是创建者嘛,就是创建的模式。
做一个音乐app,怎么个启动流程呢?
正常,有广告,有启动图,有动画,还可以可以来个启动音乐(Hello Kugou)。
这个音乐程序的基础模型就有了。顺序就是看开发者的习惯了。
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
|
package top.txiner.builder;
import java.util.ArrayList;
public abstract class Music {
private ArrayList<String> sequence = new ArrayList<String>();
protected abstract void playMusic();
protected abstract void loadSplash();
protected abstract void loadAd();
protected abstract void showAnimation();
public void run() {
for (String command : sequence) {
switch (command) {
case "music":
this.playMusic();
break;
case "splash":
this.loadSplash();
break;
case "ad":
this.loadAd();
break;
case "animation":
this.showAnimation();
break;
default:
break;
}
}
}
public void setSequence(ArrayList<String> sequence){
this.sequence=sequence;
}
}
|
具体的,播放动画,或者是加载广告,都是各家自己的标准了。
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
|
package top.txiner.builder;
import java.util.ArrayList;
public class TTPod extends Music {
@Override
protected void playMusic() {
System.out.println("TTPod can play music ");
}
@Override
protected void loadSplash() {
System.out.println("TTPod splash is beautiful");
}
@Override
protected void loadAd() {
System.out.println("TTPod no ad");
}
@Override
protected void showAnimation() {
System.out.println("TTPod animation is splendid");
}
}
package top.txiner.builder;
public class CloudMusic extends Music {
@Override
protected void playMusic() {
System.out.println("CloudMusic plays music which fits you");
}
@Override
protected void loadSplash() {
System.out.println("CloudMusic sometimes load splash");
}
@Override
protected void loadAd() {
System.out.println("CloudMusic sometimes load ad");
}
@Override
protected void showAnimation() {
System.out.println("CloudMusic animation is wonderful");
}
}
|
这样,创建app,就只需要自己写好一个序列,生成就好了。
等等,好事者称,我有国内版,国际版程序,顺序不一样,功能不一样,版本迭代的时候要求也不一样。
来,你来写呀!
(有时候客户或者pm就是好事者)
大丈夫能屈能伸,我们既然感觉这样设计太麻烦,就干脆在音乐程序上面再套个接口,不管内部的实现,直接创建就好了。
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
|
package top.txiner.builder;
import java.util.ArrayList;
public abstract class MusicBuilder {
abstract void setSequence(ArrayList<String> sequence);
abstract Music getModel();
}
package top.txiner.builder;
import java.util.ArrayList;
public class CloudMusicBuilder extends MusicBuilder {
private CloudMusic cm=new CloudMusic();
@Override
void setSequence(ArrayList<String> sequence) {
this.cm.setSequence(sequence);
}
@Override
Music getModel() {
return this.cm;
}
}
package top.txiner.builder;
import java.util.ArrayList;
public class TTPodBuilder extends MusicBuilder {
private TTPod ttPod=new TTPod();
@Override
void setSequence(ArrayList<String> sequence) {
this.ttPod.setSequence(sequence);
}
@Override
Music getModel() {
return this.ttPod;
}
}
|
这样,以后想用那个就用哪个model。
我们接下来再创建不同顺序的客户端。
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
|
package top.txiner.builder;
import java.util.ArrayList;
public class Director {
private ArrayList<String> sequence=new ArrayList<>();
private CloudMusicBuilder cmb=new CloudMusicBuilder();
private TTPodBuilder tb=new TTPodBuilder();
public TTPod getOverseaTTPod(){
this.sequence.clear();
this.sequence.add("splash");
this.sequence.add("animation");
this.sequence.add("music");
this.tb.setSequence(this.sequence);
return (TTPod) this.tb.getModel();
}
public TTPod getNativeTTPod(){
this.sequence.clear();
this.sequence.add("splash");
this.sequence.add("ad");
this.sequence.add("animation");
this.sequence.add("ad");
this.sequence.add("music");
this.tb.setSequence(this.sequence);
return (TTPod) this.tb.getModel();
}
public CloudMusic getOverseaCloudMusic(){
this.sequence.clear();
this.sequence.add("splash");
this.sequence.add("animation");
this.sequence.add("music");
this.cmb.setSequence(this.sequence);
return (CloudMusic) this.cmb.getModel();
}
public CloudMusic getNativeCloudMusic(){
this.sequence.clear();
this.sequence.add("splash");
this.sequence.add("ad");
this.sequence.add("animation");
this.sequence.add("ad");
this.sequence.add("music");
this.cmb.setSequence(this.sequence);
return (CloudMusic) this.cmb.getModel();
}
}
|
这些,主程序直接使用就好了。
1
2
3
4
5
6
7
8
9
10
11
12
|
package top.txiner.builder;
public class Client {
public static void main(String[] args) {
Director director = new Director();
CloudMusic cm=director.getOverseaCloudMusic();
cm.run();
TTPod ttPod=director.getNativeTTPod();
ttPod.run();
}
}
|
看到这也发现了,虽然我自己设计出来,确实按照我自己的想法来,可是又是序列,又是调度者的,好麻烦啊!
我有时候并不想要这么多,就是单纯的想要个属性。
所以,有一个简化的builder(如果按照定义,已经不属于这种设计模式了)
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
|
package top.txiner.builder;
import java.util.ArrayList;
public class TTPod extends Music {
private int version;
private String appName;
private String appSource;
private ArrayList<String> permissions;
private String sound;
private String size;
private String icon;
private String shortcut;
private String ctr;
public TTPod(){}
public TTPod(Builder builder) {
this.version = builder.version;
this.appName = builder.appName;
this.appSource = builder.appSource;
this.permissions = builder.permissions;
this.sound = builder.sound;
this.size = builder.size;
this.icon = builder.icon;
this.shortcut = builder.shortcut;
this.ctr = builder.ctr;
}
public static class Builder{
private int version;
private String appName;
private String appSource;
private ArrayList<String> permissions;
private String sound;
private String size;
private String icon;
private String shortcut;
private String ctr;
public Builder() {
}
public Builder setVersion(int version) {
this.version = version;
return this;
}
public Builder setAppName(String appName) {
this.appName = appName;
return this;
}
public Builder setAppSource(String appSource) {
this.appSource = appSource;
return this;
}
public Builder setPermissions(ArrayList<String> permissions) {
this.permissions = permissions;
return this;
}
public Builder setSound(String sound) {
this.sound = sound;
return this;
}
public Builder setSize(String size) {
this.size = size;
return this;
}
public Builder setIcon(String icon) {
this.icon = icon;
return this;
}
public Builder setShortcut(String shortcut) {
this.shortcut = shortcut;
return this;
}
public Builder setCtr(String ctr){
this.ctr=ctr;
return this;
}
public TTPod build(){
return new TTPod(this);
}
}
}
|
我们要使用也很简单
1
|
new TTPod.Builder().setVersion().build();
|
好了,这下很是清净了。