博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
建造者模式
阅读量:6590 次
发布时间:2019-06-24

本文共 7455 字,大约阅读时间需要 24 分钟。

建造者模式

标签 : Java与设计模式


建造者模式: 又称生成器模式, 能够将一个产品的内部表象与产品的生成过程切割开来, 从而能够使一个建造过程生成具有不同的内部表象的产品(将一个复杂对象的构建与它的表示分离, 使得同样的构建过程能够创建不同的表示). 这样用户仅仅需指定须要建造的类型就能够得到详细产品,而不须要了解详细的建造过程和细节.

  • 与抽象工厂的差别:
    在建造者模式中,角色分指导者(Director)建造者(Builder): 用户联系指导者, 指导者指挥建造者, 最后得到产品. 建造者模式能够强制实行一种分步骤进行的建造过程.

实现

需求: 模仿宇宙飞船的建造过程    如果宇宙飞船有非常多零部件: 引擎、轨道舱、逃逸塔、各种小零件... 因此宇宙飞船的建造/装配非常复杂(须要非常好的生产/装配技术),而建造者模式能够将部件的建造与装配分开:


产品与部件

产品AirShip由多个零部件(Engine/EscapeTower/OrbitalModule)组成:

/** * 目标对象 - 宇宙飞船 * (代表复杂对象, 拥有复杂的建造过程) * Created by jifang on 15/12/8. */public class AirShip {
private Engine engine; private EscapeTower escapeTower; private OrbitalModule orbitalModule; public Engine getEngine() { return engine; } public void setEngine(Engine engine) { this.engine = engine; } public EscapeTower getEscapeTower() { return escapeTower; } public void setEscapeTower(EscapeTower escapeTower) { this.escapeTower = escapeTower; } public OrbitalModule getOrbitalModule() { return orbitalModule; } public void setOrbitalModule(OrbitalModule orbitalModule) { this.orbitalModule = orbitalModule; } @Override public String toString() { return "AirShip{" + "engine=" + engine + ", escapeTower=" + escapeTower + ", orbitalModule=" + orbitalModule + '}'; }}class Engine { private String description; public Engine(String description) { this.description = description; } @Override public String toString() { return "Engine{" + "description='" + description + '\'' + '}'; }}class EscapeTower { private String description; public EscapeTower(String description) { this.description = description; } @Override public String toString() { return "EscapeTower{" + "description='" + description + '\'' + '}'; }}class OrbitalModule { private String description; public OrbitalModule(String description) { this.description = description; } @Override public String toString() { return "OrbitalModule{" + "description='" + description + '\'' + '}'; }}

建造者(Builder)

Builder(AirShipBuilder)是为创建一个Product对象的各个部件指定的抽象接口, ConcreteBuilder(LowerAirShipBuilder/HigherAirShipBuilder)是详细的建造者, 实现Builder接口, 构造和装配各个部件.

/** * @author jifang * @since 16/8/17 下午2:13. */public interface AirShipBuilder {
void builtEngine(); void builtEscapeTower(); void builtOrbitalModule(); AirShip getResult();}

生产低端飞船, 须要LowerAirShipBuilder; 生产高端飞船, 就须要HigherAirShipBuilder:

class LowerAirShipBuilder implements AirShipBuilder {    private AirShip airShip = new AirShip();    @Override    public void builtEngine() {        System.out.println("\t\t构造低端引擎");        airShip.setEngine(new Engine("低端 - 引擎"));    }    @Override    public void builtEscapeTower() {        System.out.println("\t\t构造低端逃逸塔");        airShip.setEscapeTower(new EscapeTower("低端 - 逃逸塔"));    }    @Override    public void builtOrbitalModule() {        System.out.println("\t\t构造低端轨道舱");        airShip.setOrbitalModule(new OrbitalModule("低端 - 轨道舱"));    }    @Override    public AirShip getResult() {        return airShip;    }}class HigherAirShipBuilder implements AirShipBuilder {    private AirShip airShip = new AirShip();    @Override    public void builtEngine() {        System.out.println("\t\t构造高端引擎");        airShip.setEngine(new Engine("高端 - 引擎"));    }    @Override    public void builtEscapeTower() {        System.out.println("\t\t构造高端逃逸塔");        airShip.setEscapeTower(new EscapeTower("高端 - 逃逸塔"));    }    @Override    public void builtOrbitalModule() {        System.out.println("\t\t构造高端轨道舱");        airShip.setOrbitalModule(new OrbitalModule("高端 - 轨道舱"));    }    @Override    public AirShip getResult() {        return airShip;    }}

指挥者(Director)

使用Director(AirShipDirector)控制建造过程, 也用它来隔离用户与建造过程的关联:

/** * @author jifang * @since 16/8/17 下午2:15. */public class AirShipDirector {
/** * 确定一种稳定的构造过程 * * @param builder */ public static void construct(AirShipBuilder builder) { builder.builtEngine(); builder.builtEscapeTower(); builder.builtOrbitalModule(); }}

Client

全然不需知道详细的创建/装配过程, 仅仅需指定Builder:

public class Client {    @Test    public void client() {        AirShipBuilder lowBuilder = new LowerAirShipBuilder();        // 构造低端飞船        AirShipDirector.construct(lowBuilder);        AirShip lowShip = lowBuilder.getResult();        System.out.println(lowShip);        AirShipBuilder highBuilder = new HigherAirShipBuilder();        // 同样的构造过程, 不同的Builder, 能够构造出不同的飞船        AirShipDirector.construct(highBuilder);        AirShip highShip = highBuilder.getResult();        System.out.println(highShip);    }}

实例-MyBatis中的建造者模式

MyBatis的SqlSessionFactoryBuilder是对SqlSessionFactory建造过程的简单封装,他对建造者模式做了简化处理(仅仅有Builder而无Director),以减小编程复杂度:

/** * @author Clinton Begin */public class SqlSessionFactoryBuilder {
public SqlSessionFactory build(Reader reader) { return build(reader, null, null); } public SqlSessionFactory build(Reader reader, String environment) { return build(reader, environment, null); } public SqlSessionFactory build(Reader reader, Properties properties) { return build(reader, null, properties); } public SqlSessionFactory build(Reader reader, String environment, Properties properties) { try { XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties); return build(parser.parse()); } catch (Exception e) { throw ExceptionFactory.wrapException("Error building SqlSession.", e); } finally { ErrorContext.instance().reset(); try { reader.close(); } catch (IOException e) { // Intentionally ignore. Prefer previous error. } } } public SqlSessionFactory build(InputStream inputStream) { return build(inputStream, null, null); } public SqlSessionFactory build(InputStream inputStream, String environment) { return build(inputStream, environment, null); } public SqlSessionFactory build(InputStream inputStream, Properties properties) { return build(inputStream, null, properties); } public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) { try { XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties); return build(parser.parse()); } catch (Exception e) { throw ExceptionFactory.wrapException("Error building SqlSession.", e); } finally { ErrorContext.instance().reset(); try { inputStream.close(); } catch (IOException e) { // Intentionally ignore. Prefer previous error. } } } public SqlSessionFactory build(Configuration config) { return new DefaultSqlSessionFactory(config); }}

因为SqlSessionFactory创建的SqlSession须要支持非常多操作(如selectOne()selectList()update()等), 因此SqlSessionFactory的构造过程是非常复杂的(可參考SqlSessionManagerDefaultSqlSessionFactory实现),因此使用SqlSessionFactoryBuilder作为Builder简化其构造过程,而且为其设置配置文件(mybatis-configuration.xml)作为Director来指导Builder的构造过程:

详细可參考博客:


小结

  • 因为构建装配的解耦, 不同的构建器, 同样的装配过程, 能够产生不同的产品,实现了更好的复用.因此经常使用于创建一些复杂的对象, 这些对象内部构建间的建造顺序一般是稳定的, 但内部的构建通常面临着复杂的变化. 如:
    • StringBuilderappend();
    • JDBC的PreparedStatement;
    • JDOM的DomBuilderSAXBuilder;
    • MyBatis的SqlSessionFactoryBuilder.

參考:

转载地址:http://askio.baihongyu.com/

你可能感兴趣的文章
自制基于HMM的python中文分词器
查看>>
如何在Root的手机上开启ViewServer,使得HierachyViewer能够连接
查看>>
重写和重载
查看>>
RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.2-新增锁定用户与解除锁定用户的功能...
查看>>
vue1.0 的过滤器
查看>>
如何删除anaconda
查看>>
Mybatis3.3——源码阅读笔记
查看>>
oracle中的trunc函数操作
查看>>
杂牌蓝牙在2003系统使用新驱动的破解方法!
查看>>
EventCache表太大, 怎么办?
查看>>
Top 10 mistakes in Eclipse Plug-in Development
查看>>
Directx教程(23) 简单的光照模型(2)
查看>>
使用sphinx来创建文档
查看>>
[转]用了docker是否还有必要使用openstack?
查看>>
Java 并发性和多线程
查看>>
IE6下frameset横向滚动条BUG
查看>>
命令查看java的class字节码文件
查看>>
软件下载链接获取方法
查看>>
Oracle 的一个非常好的触发器例子
查看>>
Python线程专题9:线程终止与挂起、实用工具函数
查看>>