源碼git地址 https://github.com/dlovetco/designMode
問題提出
捏兩個小人一個胖一個瘦。必須要有頭 身體 四肢。
這個場景的主要特點在於我們需要保證這個小人的穩定性, 即必須保證有客戶端在建造小人的時候有頭 身體 四肢三個部分。所以把各個部分的建造放在客戶端一定是不合適的(客戶端執行的代碼越多,越容易出錯)。
建造者模式
package builder;
public class Builder {
public static void main(String[] args) {
//捏胖子
PersonDirector fatMan = new PersonDirector(new FatBuilder());
fatMan.createPerson();
//捏瘦子
PersonDirector thinMan = new PersonDirector(new ThinBuilder());
thinMan.createPerson();
}
}
/**
* 建造者
*/
interface PersonBuilder {
void buildHead();
void buildBody();
void buildArmsAndLegs();
}
class ThinBuilder implements PersonBuilder {
@Override
public void buildHead() {
System.out.println("瘦子的頭");
}
@Override
public void buildBody() {
System.out.println("瘦子的身體");
}
@Override
public void buildArmsAndLegs() {
System.out.println("瘦子的四肢");
}
}
class FatBuilder implements PersonBuilder {
@Override
public void buildHead() {
System.out.println("胖子的頭");
}
@Override
public void buildBody() {
System.out.println("胖子的身體");
}
@Override
public void buildArmsAndLegs() {
System.out.println("胖子的四肢");
}
}
/**
* 指揮者
*/
class PersonDirector{
PersonBuilder personBuilder;
//通過構造方法來告訴指揮者要捏一個胖子還是瘦子
public PersonDirector(PersonBuilder personBuilder) {
this.personBuilder = personBuilder;
}
public void createPerson() {
personBuilder.buildHead();
personBuilder.buildBody();
personBuilder.buildArmsAndLegs();
}
}
結構大家大致看一下。其實就是先把把捏小人的過程抽象成一個接口,再用指揮者來把捏小人的過程封裝起來。因爲這幾步都是必須的,封裝起來能確保在客戶端調用的時候都會執行(這一點跟模板方法的思想有點類似)。這樣用戶在捏人的時候就不需要知道具體的步驟,只需要告訴指揮者要捏胖子還是瘦子,指揮者就會捏出相應的人物。大家自己品味一下,其實能看到我們之前學過的設計模式的一些味道。
plantuml
@startuml
interface PersonBuilder{
{abstract}buildHead()
{abstract}buildBody()
{abstract}buildArmsAndLegs()
}
PersonBuilder<|..ThinBuilder
class ThinBuilder{
buildHead()
buildBody()
buildArmsAndLegs()
}
PersonBuilder<|..FatBuilder
class FatBuilder{
buildHead()
buildBody()
buildArmsAndLegs()
}
PersonBuilder<..*PersonDirector
class PersonDirector{
PersonBuilder personBuilder
createPerson()
}
@enduml