建造者模式

Posted glsy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了建造者模式相关的知识,希望对你有一定的参考价值。

一、模式名

建造者, Builder

二、解决的问题

我们每天都在创建对象、使用对象,一般简单对象直接通过new创建即可。如果要创建的对象很复杂,或者创建对象的方式有很多,我们怎样才能做到高内聚低耦合?这时建造者模式就派上用场了。建造者模式通过抽象出某个对象的构造过程,具体构造实现交给子类完成,通过引入一个“第三者”,用于组装对象的建造过程,完成对象的构造。

看上去,这个模式和模板方法很类似,模板方法是通过父类确定解决过程,解决过程中的具体操作由子类实现。在模板方法中,父类相当于这里的第三者,负责确定具体的解决方案。这就是模板方法和建造者模式的区别。

建造者模式有两个主要的优点:

1. 复用,抽象出某个实体的构造过程方法,交给具体子类实现,通过引入“看工”,组装具体的构造过程;

2.隔离,一般客户端只需要使用“看工”完成具体实体的构造,不需要考虑看工使用了哪一个子类完成构造,有利于程序的扩展。

三、解决方案

构造者模式的UML图如下图所示。

技术图片

可以看到,定义了一个抽象类或接口Builder,其中声明了在构造过程中可能会用到的方法,还有一个Director类,即为“看工”,用于组装构造过程,对外提供构造实体的方法。

代码如下:

package com.libaoshen.java.study.java.base;

/**
 * @author libaoshen
 * @since 2020/1/13 20:18:17
 */
public class Test {
}

public class BuilderTest {
    public static void main(String[] args) {
        Builder countryBuilder = new CountryBuilder();
        Builder cityBuilder = new CityBuilder();
        Director director = new Director(countryBuilder);
        Director director2 = new Director(cityBuilder);
        director.construct();
        director2.construct();
    }
}

// 看工 
class Director {
    private Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }

    public void construct() {
        builder.start();
        builder.buildBase();
        builder.buildMiddle();
        builder.buildTop();
        builder.decorate();
        builder.end();
    }
}

// 建造者抽象类 
abstract class Builder {
    abstract void start();

    abstract void buildBase();

    abstract void buildMiddle();

    abstract void buildTop();

    abstract void decorate();

    abstract void end();
}

// 农村建房 
class CountryBuilder extends Builder {
    @Override
    void start() {
        System.out.println("开始建楼");
    }

    @Override
    void buildBase() {
        System.out.println("打水泥地基");
    }

    @Override
    void buildMiddle() {
        System.out.println("修三层砖楼");
    }

    @Override
    void buildTop() {
        System.out.println("裸露屋顶");
    }

    @Override
    void decorate() {
        System.out.println("简单装修");
    }

    @Override
    void end() {
        System.out.println("完成建楼");
    }
}

// 城市建房 
class CityBuilder extends Builder {
    @Override
    void start() {
        System.out.println("开始建楼");
    }

    @Override
    void buildBase() {
        System.out.println("修大理石地基");
    }

    @Override
    void buildMiddle() {
        System.out.println("建欧式小三楼");
    }

    @Override
    void buildTop() {
        System.out.println("修建阁楼");
    }

    @Override
    void decorate() {
        System.out.println("豪华装修");
    }

    @Override
    void end() {
        System.out.println("放置通风");
    }
}

建造者模式实践

class Request {
    private String requestMethod;
    private String requestUrl;
    private String requestHeader;
    private String requestBody;

    public Request(String requestHeader, String requestUrl, String requestBody, String requestMethod) {
        this.requestUrl = requestUrl;
        this.requestBody = requestBody;
        this.requestHeader = requestHeader;
        this.requestMethod = requestMethod;
    }

    // 静态方法,获取builder对象 
    public static RequestBuilder builder() {
        return new RequestBuilder();
    }

    @Override
    public String toString() {
        return "Request{" + "requestMethod=‘" + requestMethod + ‘‘‘ + ", requestUrl=‘" + requestUrl + ‘‘‘ + ", requestHeader=‘" + requestHeader + ‘‘‘ + ", requestBody=‘" + requestBody + ‘‘‘ + ‘}‘;
    }

    // 定义static builder 
    public static class RequestBuilder {
        private String requestMethod;
        private String requestUrl;
        private String requestHeader;
        private String requestBody;

        public RequestBuilder requestMethod(String requestMethod) {
            this.requestMethod = requestMethod;
            return this;
        }

        public RequestBuilder requestUrl(String requestUrl) {
            this.requestUrl = requestUrl;
            return this;
        }

        public RequestBuilder requestHeader(String requestHeader) {
            this.requestHeader = requestHeader;
            return this;
        }

        public RequestBuilder requestBody(String requestBody) {
            this.requestBody = requestBody;
            return this;
        }

        public Request build() {
            return new Request(this.requestHeader, this.requestUrl, this.requestBody, this.requestMethod);
        }
    }
}

常见应用场景:

1. ElasticSearch Java API中用于构造查询请求

以上是关于建造者模式的主要内容,如果未能解决你的问题,请参考以下文章

建造者模式(Builder)

设计模式之建造者模式

第十三章-建造者模式

设计模式 创建者模式 -- 建造者模式

设计模式从青铜到王者第八篇:创建型模式之建造者模式(BuilderPattern)

Java设计模式-建造者模式