23种设计模式之builder模式

最近在看图解设计模式,其中使用的是java来实现,但是发现其中有的看完后并不知道这个模式是用来干嘛的。一知半解下。通过网上资料辅助理解。就此记录。

后来发现,并不是看不懂,只是书上的例子有些比较老,对比网上的多个例子用的简化方法,书中写的例子都是经典案例,这里记录两种案例。

为什么要用builder模式

对于一个实体类,有两种方法实现构造
方法一、参数不同的构造函数

public class Computer {
     ...
    public Computer(String cpu, String ram) {
        this(cpu, ram, 0);
    }
    public Computer(String cpu, String ram, int usbCount) {
        this(cpu, ram, usbCount, "键盘");
    }
    public Computer(String cpu, String ram, int usbCount, String keyboard) {
        this(cpu, ram, usbCount, keyboard, "显示器");
    } 
}

缺点:构造函数多,当参数多时,含义不明,不易分辨。

new Computer( 1, 2, 3, 4, … )//参数多了就很繁琐

方法二、javabean模式

public class bean{
	public String username;
	public String password;
	XXXset();//实现set和get方法
	XXXget();
}

缺点:在使用中途,如果其中的属性值发生变化,要修改的不仅是字段,还有set和get方法,要改的多了,就很烦,还容易漏删、漏改。

builder模式就是为了解决这两个缺点。

什么时候用

当一个类的构造函数的参数多于四个,且有的参数是可选的,考虑使用builder模式

builder模式是什么

明白了为什么用builder和什么时候用后,就开始学习怎么用了。

常用方法(实现后可链式调用)

Computer为主类,其中定义一个静态内部类Builder,定义构造赋值必须的参数,定义set方法赋值可选的参数。

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

    private Computer(Builder builder){
        this.cpu=builder.cpu;
        this.ram=builder.ram;
        this.usbCount=builder.usbCount;
        this.keyboard=builder.keyboard;
        this.display=builder.display;
    }
    public static class Builder{//静态内部类
        private String cpu;//必须
        private String ram;//必须
        private int usbCount;//可选
        private String keyboard;//可选
        private String display;//可选

        public Builder(String cup,String ram){
            this.cpu=cup;//必选的参数,通过构造赋值
            this.ram=ram;
        }

        public Builder setUsbCount(int usbCount) {
            this.usbCount = usbCount;//可选的参数,通过set方法赋值
            return this;//链式编程的实现,返回当前的对象实例
        }
        public Builder setKeyboard(String keyboard) {
            this.keyboard = keyboard;
            return this;//链式编程的实现,返回当前的对象实例
        }
        public Builder setDisplay(String display) {
            this.display = display;
            return this;//链式编程的实现,返回当前的对象实例
        }        
        public Computer build(){
            return new Computer(this);//链式编程调用结束,返回当前的对象实例
        }
    }
  //省略getter方法
}

测试:

Computer computer=new Computer.Builder("因特尔","三星")
                .setDisplay("三星24寸")//通过链式调用,观感明了,参数设置见名知意
                .setKeyboard("罗技")
                .setUsbCount(2)
                .build();//调用结束不要忘了
传统方法

在这里插入图片描述

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 + '\'' +
                '}';
    }
}

抽象Builder类

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

    public abstract Computer getComputer();
}

具体Builder类,

//第一个具体bulider
public class MacComputerBuilder extends ComputerBuilder {
    private Computer computer;
    public MacComputerBuilder(String cpu, String ram) {
        computer = new Computer(cpu, ram);
    }
    @Override
    public void setUsbCount() {//具体的Builder类中包含其特有的set方法,且提前定义值
        computer.setUsbCount(2);
    }
    @Override
    public void setKeyboard() {
        computer.setKeyboard("苹果键盘");
    }
    @Override
    public void setDisplay() {
        computer.setDisplay("苹果显示器");
    }
    @Override
    public Computer getComputer() {
        return computer;
    }
}

//第二个具体bulider
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;
    }
}

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");
        //抽象builder用具体的builder来实例化
        director.makeComputer(builder);//通过具体的Builder类来指导Director
        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());
}

题外话:StringBuilder是可以用链式编程的


StringBuilder builder = new StringBuilder().
        builder.append("blake").append("bob").append("alice").append("linese").append("eve");

就是利用以下方式实现链式编程的

@Override
    public StringBuilder append(String str) {
        super.append(str);
        return this;//返回当前的对象实例
    }

参考:秒懂设计模式之建造者模式(Builder pattern)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值