1.问题场景:设计某个类时,需要传入多个构造器参数(如6个参数),且这些参数中有必选参数(2个)和非必选参数(4个),那么该如何设计该类的构造器会更为合理呢?
方案一:重叠构造器模式
方案二:JavaBeans模式
方案三:构建器模式
... ...
2.
重叠构造器模式
(1)形式:先提供一个包含了所有的构造参数的构造方法,再被其余的构造参数较少的构造方法来调用。简单的说,就是最终会调用到全参构造方法。
(2)好处:可降低调用者的接入成本,通常调用者都喜欢构造器的参数越少越好,通过重叠构造器模式就可以达到这种目的
。
(3)坏处:当构造器参数较多时,就会出现很多个构造方法,造成代码臃肿;当构造器参数是同一类型时,如果参数没有对号入座,编译时类型检查通过了,但是到了程序运行时才出错。
(4)具体如下:
public class AppURL {
String scheme;
String host;
String port;
String path;
String param;
public AppURL(String scheme) {
this(scheme, "");
}
public AppURL(String scheme, String host) {
this(scheme, host, "");
}
public AppURL(String scheme, String host, String port) {
this(scheme, host, port, "");
}
public AppURL(String scheme, String host, String port, String path) {
this(scheme, host, port, path, "");
}
public AppURL(String scheme, String host, String port, String path, String param) {
this.scheme = scheme;
this.host = host;
this.port = port;
this.path = path;
this.param = param;
}
}
3.JavaBeans模式
(1)定义:遵循特定规则的java类,即
必须有一个无参的构造函数、属性必须私有化、
私有化的属性必须通过公有类型的方法(get/set)对外暴露。
(2)好处:创建实例成本较低,代码实现也比较直观,即需要什么参数就指定什么参数。
(3)坏处:对象实例的构造过程被其属性的set方法所分离,难以保证线程安全;对外暴露了修改属性的途径(即set方法),对象的不可变性难以保证,即存在风险入侵口。
(4)具体如下:
public class AppURL {
String scheme;
String host;
String port;
String path;
String param;
public AppURL() {
}
public String getScheme() {
return scheme;
}
public void setScheme(String scheme) {
this.scheme = scheme;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getPort() {
return port;
}
public void setPort(String port) {
this.port = port;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getParam() {
return param;
}
public void setParam(String param) {
this.param = param;
}
}
4.构建器模式
(1)定义:
将一个复杂对象的构建和表示分离,使得同样的构建过程可以创造创建不同的表示。
(2)应用场景:适用于多个构造器参数,且参数包含必选和可选参数
(3)特点:类的构造器私有化,参数是静态Builder对象,构造过程就是将Builder的属性与类的属性一一映射。
(4)好处:可以灵活构造复杂对象实例,解决了使用JavaBeans模式来构造的问题。
(5)坏处:构造实例成本变高了,代码也变复杂了。
(5)具体如下:
public class AppURL {
String scheme;
String host;
String port;
String path;
String param;
public AppURL(Builder builder) {
scheme = builder.scheme;
host = builder.host;
port = builder.port;
path = builder.path;
param = builder.param;
}
public static class Builder {
String scheme;
String host;
String port;
String path;
String param;
public Builder setScheme(String scheme) {
this.scheme = scheme;
return this;
}
public Builder setHost(String host) {
this.host = host;
return this;
}
public Builder setPort(String port) {
this.port = port;
return this;
}
public Builder setPath(String path) {
this.path = path;
return this;
}
public Builder setParam(String param) {
this.param = param;
return this;
}
public AppURL build() {
return new AppURL(this);
}
}
}