设计模式的理解:构造器模式(Builder Pattern)

构造器模式,将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。

通俗的话来讲,就是把成员变量的初始化与构造函数进行分离。

考虑到当一个类的构造函数参数个数超过4个,而且这些参数有些是可选的参数,有些参数需要she'zhi考虑使用构造者模式。

解决的问题

当一个类的构造函数参数超过4个,而且这些参数有些是可选的时,我们通常有两种办法来构建它的对象。 例如我们现在有如下一个类计算机类Computer,其中cpu与ram是必填参数,而其他3个是可选参数,那么我们如何构造这个类的实例呢,通常有两种常用的方式:

第一:折叠构造函数模式(telescoping constructor pattern )

class Computer {
     string cpu;//必须
     string ram;//必须
     int usbCount;//可选
     string keyboard;//可选
     string display;//可选
 public:
     Computer(string cpu, string ram) {
        this(cpu, ram, 0);
    }
 Computer(string cpu, string ram, int usbCount) {
        this(cpu, ram, usbCount, "罗技键盘");
    }
 Computer(string cpu, string ram, int usbCount, string keyboard) {
        this(cpu, ram, usbCount, keyboard, "三星显示器");
    }
 Computer(string cpu, string ram, int usbCount, string keyboard, string display) {
        this->cpu = cpu;
        this->ram = ram;
        this->usbCount = usbCount;
        this->keyboard = keyboard;
        this->display = display;
    }
}

虽然,在C++语言中,可以在形参中赋默认值,但是在其他语言中,上面的表达方式弊端就十分的明显,阅读起来不方便,操作起来也不方便,当构造函数参数超过10个以上时,你在穿参初始化时很容易把值传错给其他的参数。所以builder模式就产生了

一、优化的builder模式:

两个主要的实现思路,将必须初始化的数据设置成构造函数,且构造函数不能太长,将可选的成员变量另外去赋值。

#include "iostream"
using namespace  std;
class Computer {
private:
    Computer() {

    }

 string cpu;//必须
 string ram;//必须
 int usbCount;//可选
 string keyboard;//可选
 string display;//可选
public:
class Builder{
     string cpu;//必须
     string ram;//必须
     int usbCount;//可选
     string keyboard;//可选
     string display;//可选

     public:
     Builder(string cup,string ram){
            this->cpu=cup;
            this->ram=ram;
        }

  
     const string &getCpu() const {
         return cpu;
     }

     const string &getRam() const {
         return ram;
     }

     int getUsbCount() const {
         return usbCount;
     }

     const string &getKeyboard() const {
         return keyboard;
     }

     const string &getDisplay() const {
         return display;
     }
     Builder& setUsbCount(int usbCount) {
            this->usbCount = usbCount;
            return *this;
        }
     Builder& setKeyboard(string keyboard) {
            this->keyboard = keyboard;
            return *this;
        }
     Builder& setDisplay(string display) {
            this->display = display;
            return *this;
        }
     Computer * build(){
            return new Computer(*this);
     }

    };

    //省略getter方法
 Computer(Builder builder){
        this->cpu=builder.getCpu();
        this->ram=builder.getRam();
        this->usbCount=builder.getUsbCount();
        this->keyboard=builder.getKeyboard();
        this->display=builder.getDisplay();
 }

};
int main(){
   Computer * computerPtr =  Computer::Builder("因特尔","三星")
           .setDisplay("三星24寸")
           .setKeyboard("罗技")
           .setUsbCount(2).build();
 
   return  0;
}

 

优化的builder省去了Director角色,而把Builder嵌套在实体类中,充当一个内部类。

二、传统Builder 模式

 

 

最原先的builder 模式有一个director类,

1.在builder抽象类中,将实体类Product的可选成员参数的赋值设置为抽象函数,必选成员变量设置为Product实体类和 Builder派生类的构造函数。

2.Procuct 为 Builder派生类 的子对象

3.director 负责初始化  Builder。

 

1) 定义实体类

public class Computer {
    private String cpu;//必须
    private String ram;//必须
    private int usbCount;//可选
    private String keyboard;//可选
    private String display;//可选

    public Computer(String cpu, String ram) {
        this.cpu = cpu;
        this.ram = ram;
    }
    public void setUsbCount(int usbCount) {
        this.usbCount = usbCount;
    }
    public void setKeyboard(String keyboard) {
        this.keyboard = keyboard;
    }
    public void setDisplay(String display) {
        this.display = display;
    }
    @Override
    public String toString() {
        return "Computer{" +
                "cpu='" + cpu + '\'' +
                ", ram='" + ram + '\'' +
                ", usbCount=" + usbCount +
                ", keyboard='" + keyboard + '\'' +
                ", display='" + display + '\'' +
                '}';
    }
}

2)抽象Builder类 和 派生类

public abstract class ComputerBuilder {
    public abstract void setUsbCount();
    public abstract void setKeyboard();
    public abstract void setDisplay();

    public abstract Computer getComputer();
}

 

//苹果电脑构建者
public class MacComputerBuilder extends ComputerBuilder {
    private Computer computer;
    public MacComputerBuilder(String cpu, String ram) {
        computer = new Computer(cpu, ram);
    }
    @Override
    public void setUsbCount() {
        computer.setUsbCount(2);
    }
    @Override
    public void setKeyboard() {
        computer.setKeyboard("苹果键盘");
    }
    @Override
    public void setDisplay() {
        computer.setDisplay("苹果显示器");
    }
    @Override
    public Computer getComputer() {
        return computer;
    }
}

 

//联想电脑构建者类
public class LenovoComputerBuilder extends ComputerBuilder {
    private Computer computer;
    public LenovoComputerBuilder(String cpu, String ram) {
        computer=new Computer(cpu,ram);
    }
    @Override
    public void setUsbCount() {
        computer.setUsbCount(4);
    }
    @Override
    public void setKeyboard() {
        computer.setKeyboard("联想键盘");
    }
    @Override
    public void setDisplay() {
        computer.setDisplay("联想显示器");
    }
    @Override
    public Computer getComputer() {
        return computer;
    }
}

3) director  类

public class ComputerDirector {
    public void makeComputer(ComputerBuilder builder){
        builder.setUsbCount();
        builder.setDisplay();
        builder.setKeyboard();
    }
}

 

使用案例:

public static void main(String[] args) {
        ComputerDirector director=new ComputerDirector();//1
        ComputerBuilder builder=new MacComputerBuilder("I5处理器","三星125");//2
        director.makeComputer(builder);//3
        Computer macComputer=builder.getComputer();//4
        System.out.println("mac computer:"+macComputer.toString());

        ComputerBuilder lenovoBuilder=new LenovoComputerBuilder("I7处理器","海力士222");
        director.makeComputer(lenovoBuilder);
        Computer lenovoComputer=lenovoBuilder.getComputer();
        System.out.println("lenovo computer:"+lenovoComputer.toString());
}

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Builder设计模式是一种创建型设计模式,它用于创建复杂对象,将对象的构建过程与其表示分离。该设计模式使用一个独立的Builder类来构建对象,而不需要直接使用对象的构造函数。 使用Builder设计模式可以将对象的构建逻辑集中在一个地方,使得代码更加清晰和可读,并且便于维护和扩展。它主要包含以下几个角色: 1. Product(产品):产品类是要创建的复杂对象。它包含多个属性,以及对属性赋值的方法。 2. Builder(抽象建造者):Builder类是一个接口或抽象类,定义了构建产品的方法,包括设置产品的属性以及返回构建好的产品。 3. ConcreteBuilder(具体建造者):ConcreteBuilder类实现了Builder接口,实现了构建产品的具体逻辑,包括设置产品的各个属性,并返回构建好的产品。 4. Director(指挥者):Director类是一个调用者,它负责调用具体建造者来构建产品。它将具体建造者和产品分离,只通过接口或抽象类与它们交互。 使用Builder设计模式的典型步骤如下: 1. 创建产品类,定义产品的属性和方法。 2. 创建抽象建造者接口或抽象类,定义构建产品的方法。 3. 创建具体建造者类,实现抽象建造者接口或抽象类,在其中定义具体的产品构建逻辑。 4. 创建指挥者类,负责调用具体建造者来构建产品。 通过以上步骤,我们可以通过调用指挥者的构建方法,来获取构建好的产品对象。使用Builder设计模式,我们可以将产品的构建过程与表示分离,使得产品构建的灵活性和可扩展性增强。同时,也可以降低客户端使用产品构建过程的复杂性,使得客户端的代码更加简洁和易于维护。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值