0
点赞
收藏
分享

微信扫一扫

建造者模式(Builder pattern)—— 帮你更好的创建复杂对象

建造者模式是将一个复杂对象的构建与它的表示分离,各自独立,同样的构建过程可以有不同的表现。 

一、你会怎么办?

对于复杂对象,那假如一个类的构造函数参数个数超过4个,而且这些参数有些是可选的参数,你要怎样将这个类实例化?可以有两种方式:

比如我们要画一个人,这个人有头、手、脚、身体这些必选项,也有衣服、鞋子、帽子这些可选项。

public class PersonDraw1 {
// 必选属性
private String head;
private String hand;
private String foot;
private String body;
// 可选项
private String clothes;
private String shoes;
private String hat;
}

 第一种:折叠构造方法模式

public class PersonDraw1 {
// 必选属性
private String head;
private String hand;
private String foot;
private String body;
// 可选项
private String clothes;
private String shoes;
private String hat;

public PersonDraw1(String head, String hand, String foot, String body) {
this.head = head;
this.hand = hand;
this.foot = foot;
this.body = body;
}

public PersonDraw1(String head, String hand, String foot, String body, String clothes) {
this.head = head;
this.hand = hand;
this.foot = foot;
this.body = body;
this.clothes = clothes;
}

public PersonDraw1(String head, String hand, String foot, String body, String clothes, String shoes) {
this.head = head;
this.hand = hand;
this.foot = foot;
this.body = body;
this.clothes = clothes;
this.shoes = shoes;
}

public PersonDraw1(String head, String hand, String foot, String body, String clothes, String shoes, String hat) {
this.head = head;
this.hand = hand;
this.foot = foot;
this.body = body;
this.clothes = clothes;
this.shoes = shoes;
this.hat = hat;
}
}

第二种:Javabean 模式

@Getter
@Setter
public class PersonDraw1 {
// 必选属性
private String head;
private String hand;
private String foot;
private String body;
// 可选项
private String clothes;
private String shoes;
private String hat;
}

第一种:调用一个类的构造函数时要决定使用哪一个,且还要考虑参数含义及顺序。

第二种:在构建过程中对象的状态容易发生变化,造成错误。

以上两种方式在创建对象时,可能造成对象不完整,少了某个属性或流程。要是少了必选项这个对象就没意义了,比如这个人缺胳膊少腿。

二、建造者模式

上面的问题,使用建造者模式可以解决。

@Getter
@ToString
public class PersonDraw {
// 必选属性
private String head;
private String hand;
private String foot;
private String body;
// 可选项
private String clothes;
private String shoes;
private String hat;

public PersonDraw(Builder builder){
this.head = builder.head;
this.hand = builder.hand;
this.foot = builder.foot;
this.body = builder.body;
this.clothes = builder.clothes;
this.shoes = builder.shoes;
this.hat = builder.hat;
}

public static class Builder {
// 必选属性
private String head;
private String hand;
private String foot;
private String body;
// 可选项
private String clothes;
private String shoes;
private String hat;

public Builder (String head, String hand, String foot, String body){
this.head = head;
this.hand = hand;
this.foot = foot;
this.body = body;
}

public Builder setClothes(String clothes){
this.clothes = clothes;
return this;
}

public Builder setShoes(String shoes) {
this.shoes = shoes;
return this;
}

public Builder setHat(String hat) {
this.hat = hat;
return this;
}

public PersonDraw build(){
return new PersonDraw(this);
}
}
}
public class Client {
public static void main(String[] args) {
PersonDraw personDraw = new PersonDraw.Builder("头", "手", "脚", "身体")
.setClothes("衣服")
.build();
Console.log(personDraw.toString());
Console.log(personDraw.getFoot());
}
}
PersonDraw(head=头, hand=手, foot=脚, body=身体, clothes=衣服, shoes=null, hat=null)
  1. 在 PersonDraw 中创建一个静态内部类 Builder,然后将 PersonDraw 中的参数都复制到Builder类中。
  2. 在 PersonDraw 中创建一个private的构造函数,参数为Builder类型。
  3. 在Builder中创建一个构造函数,参数为 PersonDraw 中必填的那些参数。
  4. 在Builder中创建设置函数,对那些可选参数进行赋值,返回值为Builder类型的实例。
  5. 在Builder中创建一个​​build()​​方法,在其中构建 PersonDraw 的实例并返回。

三、建造者模式适用场景

优点:

  1.客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。

  2.每一个具体建造者都独立,因此可以方便地替换具体建造者或增加新的具体建造者, 用户使用不同的具体建造者即可得到不同的产品对象 。

  3.可以更加精细地控制产品的创建过程 。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰。

缺点:

  1.当建造者过多时,会产生很多类,难以维护。

  2.建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,若产品之间的差异性很大,则不适合使用该模式。

  3.若产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。

适用场景:

       1.创建复杂对象的算法独立于组成对象的部件

       2.同一个创建过程需要有不同的内部表象的产品对象

但一般当一个类的构造函数参数个数超过4个,而且这些参数有些是可选的参数,考虑使用构造者模式。


举报

相关推荐

0 条评论