JAVA设计模式大总结系列博客(四)高度灵活的构建者模式

老规矩,先看定义

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

又是一脸懵逼对吧?我也是,但是这些都可以放在后边解决,现在需要解决的是,如何使用。我们不用说每次都要先搞清楚概念,应该是先学代码,至于其中的道理和那些晦涩难懂的术语,可以先放下,时间到了,自然就懂了,无论学什么知识都是如此。

那么,构建者模式的使用场景是什么?

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

这个意思比较简单,意思就是一个类有可选参数而且个数多的时间,可以使用这个模式。

我们来通过例子说明吧。

package com.heigherjavatest.designpattern.builder;
/*
 * 【Author】 技术支持史
 * 【Time】2020年5月24日 下午2:09:33
 * 【Function】  目标类
 */
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 + '\'' +
                '}';
    }
}

这个是一个有可选参数的类吧。然后,我们创建一个

package com.heigherjavatest.designpattern.builder;
/*
 * 【Author】 技术支持史
 * 【Time】2020年5月24日 下午2:11:13
 * 【Function】抽象的构建者
 */
public abstract class ComputerBuilder {
	
    public abstract void setUsbCount();
    public abstract void setKeyboard();
    public abstract void setDisplay();

    public abstract Computer getComputer();
}

这个是用来干什么的?先不要急,我们在写两个类你就知道了

package com.heigherjavatest.designpattern.builder;
/*
 * 【Author】 技术支持史
 * 【Time】2020年5月24日 下午2:12:49
 * 【Function】联想电脑构建者类
 */
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;
    }
}

再来一个

package com.heigherjavatest.designpattern.builder;
/*
 * 【Author】 技术支持史
 * 【Time】2020年5月24日 下午2:09:33
 * 【Function】  目标类
 */
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 + '\'' +
                '}';
    }
}

明白了吗? 上面两个类继承了最初的那个抽象类ComputerBuilder,目的就是为了用抽象类里面的方法,用于设置可选参数的值和获取到最后的电脑的信息。
只有这些吗?不,我们还缺少一个类

package com.heigherjavatest.designpattern.builder;
/*
 * 【Author】 技术支持史
 * 【Time】2020年5月24日 下午2:13:24
 * 【Function】指导者类(Director)
 */
public class ComputerDirector {
	
    public void makeComputer(ComputerBuilder builder){
        builder.setUsbCount();
        builder.setDisplay();
        builder.setKeyboard();
    }
}

这个是用来做什么呢?在笔者看来,它是最大的Boss,管理所有的构造者,它里面的makeComputer 方法可以看作是个构造器。传入的参数正是抽线类的实例ComputerBuilder 用于接收不同的电脑,无论是什么电脑都可以用它表示。传入电脑后,它就调用里面的setXXX方法,将可选的信息设置到对应的电脑里面。最后,我们来测试一下

package com.heigherjavatest.designpattern.builder;
/*
 * 【Author】 技术支持史
 * 【Time】2020年5月24日 下午2:15:02
 * 【Function】
 */
public class Main {
	
	public static void main(String[] args) {
		//电脑指导者类
        ComputerDirector director=new ComputerDirector();
        // 构建苹果电脑
        ComputerBuilder builder=new MacComputerBuilder("苹果I5处理器","苹果运行内存");
        director.makeComputer(builder);//构建了
        Computer macComputer=builder.getComputer();//构建之后  获得这个电脑的信息
        System.out.println("我的苹果:"+macComputer.toString());

        ComputerBuilder lenovoBuilder=new LenovoComputerBuilder("联想I7处理器","联想运行内存");
        director.makeComputer(lenovoBuilder);
        Computer lenovoComputer=lenovoBuilder.getComputer();
        System.out.println("我的联想:"+lenovoComputer.toString());
}
}

打印结果:

  • 我的苹果:Computer{cpu=‘苹果I5处理器’, ram=‘苹果运行内存’, usbCount=2, keyboard=‘苹果键盘’, display=‘苹果显示器’}
  • 我的联想:Computer{cpu=‘联想I7处理器’, ram=‘联想运行内存’, usbCount=4, keyboard=‘联想键盘’, display=‘联想显示器’}

看明白了吗?这里其实就是我创建了一个主要的电脑信息,其他的可选信息是通过构造者进行设置,最后输出的时候依然打印出来了,这样,我们就可以把主要注意力集中到主要参数上,不必关注可选参数,他们由构造器自动管理。

当中难免有纰漏,欢迎大家一起讨论补充!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱吃早餐的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值