@

最近在看Mybatis的源码, 在阅读解析 XML 配置文件的过程中, 发现使用到了建造者(Builder)模式。 因此, 打算重温一下该设计模式。

由来

假设我们需要画一个小人, 我们可能会有以下的构造函数定义:

public Person(HeadType headType, HairType hairType, HairColor hairColor, FaceType faceType, BodyType bodyType, ArmType amrType, LegType legTyype) {
}

看到这么一个构造函数, 估计我们自己以后回来看的时候都懵了, 这么多参数, 导致我们后续的维护也很麻烦。

而构造模式就可以解决此类的问题。

使用

目标是画一个小人

1. 定义抽象 Builder

先定义抽象的PersonBuilder。 该类定义了画小人需要的步骤, 这样每个通过PersonBuilder产生的对象本质上就都是一样的了, 只不过个性上可以不一样。

abstract class PersonBuilder {
protected Graphics graphics; public PersonBuilder(Graphics graphics) {
this.graphics = graphics;
} public abstract void buildHead();
public abstract void buildBody();
public abstract void buildArmLeft();
public abstract void buildArmRight();
public abstract void buildLegLeft();
public abstract void buildLegRight();
}

2. 定义具体 Builder

在定义一个具体的实现类PersonFatBuilder。 该类继承PersonBuilder, 并实现了抽象方法。

public class PersonFatBuilder extends PersonBuilder {
public PersonFatBuilder(Graphics graphics) {
super(graphics);
}
@Override
public void buildHead() {
graphics.drawOval(50, 20, 30, 30);
graphics.drawArc(50, 30, 10, 5, 45, 135);
graphics.drawArc(70, 30, 10, 5, 45, 135);
graphics.drawArc(60, 35, 10, 5, 200, 135);
} @Override
public void buildBody() {
graphics.drawRect(55, 50, 20, 50);
} @Override
public void buildArmLeft() {
graphics.drawLine(55, 50, 40, 100);
} @Override
public void buildArmRight() {
graphics.drawLine(75, 50, 90, 100);
} @Override
public void buildLegLeft() {
graphics.drawLine(55, 100, 45, 150);
} @Override
public void buildLegRight() {
graphics.drawLine(75, 100, 85, 150);
}
}

3. 定义具体 Director

该类负责具体的建造过程, 对建成什么样不关心。

public class PersonDirector {
private PersonBuilder personBuilder; public PersonDirector(PersonBuilder personBuilder) {
this.personBuilder = personBuilder;
} public void drawPerson() {
personBuilder.buildHead();
personBuilder.buildBody();
personBuilder.buildArmLeft();
personBuilder.buildArmRight();
personBuilder.buildLegLeft();
personBuilder.buildLegRight();
}
}

4. 测试

建立一个窗口,将小人画出来。

 public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
// 创建窗口对象
JFrame frame = new JFrame();
frame.setVisible(true);
frame.setTitle("画人");
frame.setSize(250, 300); // 设置窗口关闭按钮的默认操作(点击关闭时退出进程)
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); // 把窗口位置设置到屏幕的中心
frame.setLocationRelativeTo(null);
frame.setContentPane(new JPanel(){
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
PersonThinBuilder thinBuilder = new PersonThinBuilder(g);
PersonDirector director = new PersonDirector(thinBuilder);
director.drawPerson(); }
});
}
});
}

结果如下:

定义

文字定义

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

换句话解释, 允许你创建不同种类的对象, 同时又能避免对构造函数的污染。当对象有多种类型时, 该模式非常有用。 或者在创建对象时涉及到很多的步骤。

结构图

引用《大话设计模式》的一个图

抽象类Builder:为创建Product对象而抽象的接口。

继承类ConcreateBuilder:具体的建造者, 构造和装配各个部件。

具体产品类Product:我们需要建造的对象。

Director: 用来创建产品的, 其内部有Builder类型的成员变量。

优点

  1. Director 不需要知道 Product 的内部细节, 它只提供需要的信息给建设者, 由具体的建造者ConcreateBuilder处理从而完成产品的构造。
  2. 建造者模式将复杂的产品创建过程分散到了不同的对象中, 从而实现对产品创建过程更精确的控制, 创建过程更加清晰。
  3. 每个具体的建造者都可以创建出完整的产品对象, 而且是相互独立的。 因此, 调用端可以通过不同的具体建造者就可以得到不同的对象。当有新的产品出现时, 不需要改变原有代码, 只需要添加一个建造者即可。

举例

现在如果我们想建造一个胖小人,有五官的。那我们只需要添加一个PersonFatBuilder类就可以了, 不需要改原有代码。

public class PersonFatBuilder extends PersonBuilder {
public PersonFatBuilder(Graphics graphics) {
super(graphics);
}
@Override
public void buildHead() {
graphics.drawOval(50, 20, 30, 30);
graphics.drawArc(50, 30, 10, 5, 45, 135);
graphics.drawArc(70, 30, 10, 5, 45, 135);
graphics.drawArc(60, 35, 10, 5, 200, 135);
} @Override
public void buildBody() {
graphics.drawRect(55, 50, 20, 50);
} @Override
public void buildArmLeft() {
graphics.drawLine(55, 50, 40, 100);
} @Override
public void buildArmRight() {
graphics.drawLine(75, 50, 90, 100);
} @Override
public void buildLegLeft() {
graphics.drawLine(55, 100, 45, 150);
} @Override
public void buildLegRight() {
graphics.drawLine(75, 100, 85, 150);
}
}

结果:

Java设计模式-建造者(Builder)模式的更多相关文章

  1. Java设计模式之builder模式

    Java设计模式之builder模式 今天学mybatis的时候,知道了SQLSessionFactory使用的是builder模式来生成的.再次整理一下什么是builder模式以及应用场景. 1. ...

  2. 设计模式--建造者(Builder)模式

    将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示                                                         --<设计模 ...

  3. 3.java设计模式-建造者模式

    Java设计模式-建造者模式 在<JAVA与模式>一书中开头是这样描述建造(Builder)模式的: 建造模式是对象的创建模式.建造模式可以将一个产品的内部表象(internal repr ...

  4. 设计模式:Builder模式

    设计模式:Builder模式 一.前言    今天我们讨论一下Builder建造者模式,这个Builder,其实和模板模式非常的像,但是也有区别,那就是在模板模式中父类对子类中的实现进行操作,在父类之 ...

  5. 折腾Java设计模式之模板方法模式

    博客原文地址:折腾Java设计模式之模板方法模式 模板方法模式 Define the skeleton of an algorithm in an operation, deferring some ...

  6. java设计模式6--适配器模式(Adapter )

    本文地址:http://www.cnblogs.com/archimedes/p/java-adapter-pattern.html,转载请注明源地址. 适配器模式(别名:包装器) 将一个类的接口转换 ...

  7. java设计模式5--原型模式(Prototype)

    本文地址:http://www.cnblogs.com/archimedes/p/java-prototype-pattern.html,转载请注明源地址. 原型模式 用原型实例指定创建对象的种类,并 ...

  8. Java设计模式——装饰者模式

    JAVA 设计模式 装饰者模式 用途 装饰者模式 (Decorator) 动态地给一个对象添加一些额外的职责.就增加功能来说,Decorator 模式相比生成子类更为灵活. 装饰者模式是一种结构式模式 ...

  9. 浅析JAVA设计模式之工厂模式(一)

    1 工厂模式简单介绍 工厂模式的定义:简单地说,用来实例化对象,取代new操作. 工厂模式专门负责将大量有共同接口的类实例化.工作模式能够动态决定将哪一个类实例化.不用先知道每次要实例化哪一个类. 工 ...

随机推荐

  1. C#多线程的用法6-线程间的协作Mutex

    Mutex在线程协作的过程中起互斥的左右,效果与线程锁类似. /// <summary> /// 多线程协作-Mutex /// </summary> private stat ...

  2. nmcli 命令使用

    nmcli 是 NetworkManager 的控制客户端,通过 man 查看可知: NMCLI(1) General Commands Manual NMCLI(1) NAME nmcli - co ...

  3. October 20th 2017 Week 42nd Friday

    My life is in these books. Read these and know my heart. 我的人生就在这些书中,读完他们就能读懂我的心. Some people say tha ...

  4. SDN2017 第四次实验作业

    实验目的 1.使用图形化界面搭建拓扑如下并连接控制器 2.使用python脚本搭建拓扑如下并通过命令行连接控制器 3.使用任一种方法搭建拓扑连接控制器后下发流表 实验步骤 建立以下拓扑,并连接上ODL ...

  5. toFixed四舍五入精度校正

    var a = 2.255; var b = a.toFixed(2); console.log(b); 以上代码,按预期正常四舍五入得到结果应该是2.26,但实际返回值为2.25 js浮点数精度作为 ...

  6. A “Type Erasure” Pattern that Works in Swift:类型域的转换

    新视角:通过函数式编程的范畴理论来看待这个问题会更容易理解: 在低层类型无法很好表达的类型,可以将其转化为高阶类型进行表示. 将协议的实现类型转化为monad类型: 解决将具有关联类型的协议当作类型的 ...

  7. ubuntu 视频播放问题

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/chang_xing/article/details/30976659                ...

  8. aused by: org.apache.xmlbeans.SchemaTypeLoaderException: XML-BEANS compiled schema: Incompatible min

    版权声明:转载请注明出处 https://blog.csdn.net/seashouwang/article/details/24025871 6.导入Word2007-docx,Excel-2007 ...

  9. 【Java集合源代码剖析】ArrayList源代码剖析

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/mmc_maodun/article/details/35568011 转载请注明出处:http:// ...

  10. Solr建立索引时,过滤HTML标签

    原文地址  http://www.joyphper.net/article/201306/188.html 1.在数据库的读取文件data-config.xml 中的entity 标记里边添加 tra ...