作者持续关注 WPS二次开发专题系列,持续为大家带来更多有价值的WPS开发技术细节,如果能够帮助到您,请帮忙来个一键三连,更多问题请联系我(QQ:250325397)

定义

造者模式(Builder Pattern):使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。

特点

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

使用场景

  • 相同的方法,不同的执行顺序,产生不同的结果。
  • 多个部件或零件,都可以装配到一个对象中,但是产生的结果又不相同。
  • 产品类非常复杂,或者产品类中不同的调用顺序产生不同的作用。
  • 初始化一个对象特别复杂,参数多,而且很多参数都具有默认值。

优缺点

(1) 优点

  • 封装性好,构建和表示分离。
  • 扩展性好,各个具体的建造者相互独立,有利于系统的解耦。
  • 客户端不必知道产品内部组成的细节,建造者可以对创建过程逐步细化,而不对其它模块产生任何影响,便于控制细节风险。

(2) 缺点

  • 产品的组成部分必须相同,这限制了其使用范围。
  • 如果产品的内部变化复杂,如果产品内部发生变化,则建造者也要同步修改,后期维护成本较大。

模式结构

建造者(Builder)模式的主要角色如下。

  • 产品角色(Menu):它是包含多个组成部件的复杂对象,由具体建造者来创建其各个零部件。
  • 抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法 build()。
  • 具体建造者(Concrete Builder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。
  • 指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。

设计模式-构建者模式_建造者

具体实现

(1) 方式1

抽象构建器和菜单项

/**
 * 抽象的构造器
 */
public abstract class Builder {

    protected Menu menu = new Menu();

    /**
     * 构建复制菜单项
     */
    abstract void buildCopyMenuItem();

    /**
     * 构建粘贴菜单项
     */
    abstract void buildPasteMenuItem();

    /**
     * 构建剪切菜单项
     */
    abstract void buildCutMenuItem();

    public Menu getMenu() {
        return menu;
    }
}

/**
 * 手机版的菜单构建器
 */
public class PhoneMenuBuilder extends Builder {
    @Override
    void buildCopyMenuItem() {
        MenuItem menuItem = new MenuItem(1, "复制", 1);
        menu.setCopyMenuItem(menuItem);
    }

    @Override
    void buildPasteMenuItem() {
        MenuItem menuItem = new MenuItem(2, "粘贴", 2);
        menu.setPasteMenuItem(menuItem);
    }

    @Override
    void buildCutMenuItem() {
        MenuItem menuItem = new MenuItem(3, "剪切", 3);
        menu.setCutMenuItem(menuItem);
    }
}

/**
 * 菜单
 */
public class Menu {

    /**
     * 复制菜单项
     */
    private MenuItem copyMenuItem;

    /**
     * 粘贴菜单项
     */
    private MenuItem pasteMenuItem;

    /**
     * 剪贴菜单项
     */
    private MenuItem cutMenuItem;
}

构建指挥者

/**
 * 指挥者
 */
public class Director {

    private Builder builder;

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

    /**
     * 构建菜单
     */
    public Menu construct() {
        builder.buildCopyMenuItem();
        builder.buildPasteMenuItem();
        builder.buildCutMenuItem();
        return builder.getMenu();
    }

}

具体使用

public class App {

    public static void main(String[] args) {
        //构建菜单
        Builder builder = new PhoneMenuBuilder();
        Director director = new Director(builder);
        Menu menu = director.construct();
        System.out.println("menu:" + menu);
    }
}

(2) 方式2

内部内的构建器,链式编程

/**
 * http请求
 */
public class HttpRequest {
    private String url;

    private String contentType;

    private String method;

    private String body;

    public String getUrl() {
        return url;
    }

    public String getContentType() {
        return contentType;
    }

    public String getMethod() {
        return method;
    }

    public String getBody() {
        return body;
    }

    public static class Builder {
        private String url;

        private String contentType;

        private String method;

        private String body;

        public Builder setUrl(String url) {
            this.url = url;
            return this;
        }

        public Builder setContentType(String contentType) {
            this.contentType = contentType;
            return this;
        }

        public Builder setMethod(String method) {
            this.method = method;
            return this;
        }

        public Builder setBody(String body) {
            this.body = body;
            return this;
        }

        public HttpRequest build() {
            HttpRequest httpRequest = new HttpRequest();
            httpRequest.url = this.url;
            httpRequest.contentType = this.contentType;
            httpRequest.method = this.method;
            httpRequest.body = this.body;

            return httpRequest;
        }
    }
}

具体使用

public class App {
    public static void main(String[] args) {
        //构建请求信息
        HttpRequest httpRequest = new HttpRequest.Builder()
                .setUrl("http://www.xxx.com")
                .setContentType("application/json")
                .setMethod("POST")
                .setBody("123")
                .build();
        System.out.println("httpRequest:" + httpRequest);
    }
}

实际应用

1、游戏软件中,地图包括天空、地面、背景等组成部分,人物角色包括人体、服装、装备等组成部分,可以使用建造者模式对其进行设计,通过不同的具体建造者创建不同类型的地图或人物。

2、复杂对象的构建,如StringBuilder、wps各组件菜单的MenuBuilder、OKHttp网络库的HttpRequestBuilder等。