源码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