Builder模式

1.定义

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

2.使用场景

(1)相同的方法,不同的执行顺序,产生不同的事件结果时。 (2)多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时。 (3)产品类非常复杂,或者产品类中的调用顺序不同产生了不同的作用,这个使用建造者模式非常适合。 (4)当初始化一个对象特别复杂时,如参数多,且很多参数有默认值。

3.简单实现

定义一个要建造对象的抽象类和实现类

//抽象类
public abstract class Computer {
    protected String mOS;
    protected String mBoard;
    protected String mDisplay;

    public void setBoard(String mBoard) {
        this.mBoard = mBoard;
    }
    public void setDisplay(String mDisplay) {
        this.mDisplay = mDisplay;
    }

    public abstract void setOS();

    @Override
    public String toString() {
        return "Computer [mOS=" + mOS + ", mBoard=" + mBoard + ", mDisplay="
                + mDisplay + "]";
    }
}

//实现类
public class MacComputer extends Computer {
    @Override
    public void setOS() {
        mOS = "Mac";
    }
}

再定义一个抽象的builder类和builder实现类

public abstract class Builder {
    public abstract Builder setBoard(String mBoard);

    public abstract Builder setDisplay(String mDisplay);

    public abstract Builder setOS();

    public abstract Computer create();
}

public class MacBookBuilder extends Builder {

    private Computer mComputer = new MacComputer();

    @Override
    public Builder setBoard(String mBoard) {
        mComputer.setBoard(mBoard);
        return this;
    }

    @Override
    public Builder setDisplay(String mDisplay) {
        mComputer.setDisplay(mDisplay);
        return this;
    }

    @Override
    public Builder setOS() {
        mComputer.setOS();
        return this;
    }

    @Override
    public Computer create() {
        return mComputer;
    }

}

测试代码就一句话

    public static void main(String[] args) {
        Computer computer = new MacBookBuilder().setBoard("111")
                .setDisplay("222").setOS().create();
        System.out.println(computer);
    }

你会发现他和装饰类有点像,参考资料在这里: http://blog.csdn.net/u010955843/article/details/24875903

4.总结

优点: (1)良好的封装性,使用建造者模式可以使客户端不必知道产品内部组成细节。 (2)建造者独立,容易扩展。 缺点: (1)会产生多余的Builder对象及Director对象(这里被我简化了),消耗内存。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 再忆RxJava---线程切换

    RxJava已经陆陆续续看了将近两年多了,觉得很有必要重新认识一下。而且最新github上都出了3.0了。重新看一下,一来作为回顾,二来也算是学习一下3.0 ...

    提莫队长
  • 简单介绍ASM核心API

    它的调用顺序是首先调用 visit,然后是对 visitSource 的最多一个调用,接下来是对 visitOuterClass 的最多一个调用,然后是可按任意...

    提莫队长
  • okhttp拦截器的使用------修改baseurl

    有的时候做项目的时候会遇到调用接口的url和之前接口定义的url不一样,很可能连retrofit已经设置好的baseurl都要换,但是retrofit并没有提供...

    提莫队长
  • 深入理解String类

    String是java中的字符串。String类是不可变的,对String类的任何改变,都是返回一个新的String类对象。String不属于8种基本数据类型,...

    栋先生
  • java使用influxDB时序数据库

    InfluxDB的字段类型,由第一条插入的值得类型决定;tags的类型只能是String型,可以作为索引,提高检索速度。

    半条命专刊
  • Android 二次封装网络加载框架

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gdutxiaoxu/article/de...

    用户2965908
  • SpringBoot2.x系列教程(二十九)freemarker自动配置源码解析

    在前几节中我们讲了SpringBoot中集成freemarker及其相关功能的使用。这篇文章我们从源码层面来看看,SpringBoot中freemarker相关...

    用户1161110
  • 建造者模式(Builder)及其应用

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gdutxiaoxu/article/details/...

    用户2965908
  • Eclipse中java向数据库中添加数据,更新数据,删除数据

    前面详细写过如何连接数据库的具体操作,下面介绍向数据库中添加数据。 注意事项:如果参考下面代码,需要 改包名,数据库名,数据库账号,密码,和数据表(数据表里面的...

    别先生
  • Java8-Lambda表达式-函数式接口

    Erwin

扫码关注云+社区

领取腾讯云代金券