作者持续关注WPS二次开发专题系列,持续为大家带来更多有价值的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等。