建造模式详解

建造模式详解

理解

当创建一个复杂对象时,这个对象由各个部分的子对象构成,这个复杂对象的各个部分经常面临着剧烈的变化。我理解的主要有两种建造模式,一些基本部件不会变,而其组合经常变化的时候,例如餐厅点餐;另外一种是,组合不会改变,或是部件的装配的顺序一定时,例如电脑的构建。

示例

随意组合的建造模式

模拟餐厅点餐的系统:其中提供Edible接口,代表可食用的食物,若干食物类对其实现。Combo是套餐容器类,ComboBuilder可建造出套餐。
在这里插入图片描述
接口:

public interface Edible {

    void eat();
}
public interface Dishes extends Edible {
}
public interface Drinks extends Edible {
}
public interface Meal extends Edible {
}

实现:

public class Bread implements Meal {

    @Override
    public void eat() {
        System.out.println("bread was eaten");
    }
}
public class Cola implements Drinks {

    @Override
    public void eat() {
        System.out.println("cola was drunk");
    }
}

public class FriedChicken implements Dishes {

    @Override
    public void eat() {
        System.out.println("friedChicken was eaten");
    }
}
public class FryMeat implements Dishes {
    @Override
    public void eat() {
        System.out.println("FryMeat was eaten");
    }
}
public class Juice implements Drinks {

    @Override
    public void eat() {
        System.out.println("juice was drunk");
    }
}
public class Noodle implements Meal {

    @Override
    public void eat() {
        System.out.println("noodle was eaten");
    }
}
public class Rice implements Meal {

    @Override
    public void eat() {
        System.out.println("rice was eaten");
    }
}
public class Soup implements Drinks {

    @Override
    public void eat() {
        System.out.println("soup was drunk");
    }
}

套餐容器类:

public class Combo {

    List<Edible> combo;

    Combo() {
        this.combo = new ArrayList<>();
    }

    public List<Edible> getCombo() {
        return combo;
    }
}

套餐构建类

public class ComboBuilder {

    Combo combo;

    public ComboBuilder() {
        combo = new Combo();
    }

    public ComboBuilder append(Edible edible) {
        combo.getCombo().add(edible);
        return this;
    }

    public Combo build() {
        return combo;
    }
}

测试Main方法

public static void main(String[] args) {
    System.out.println("套餐一");
    Combo combo = new ComboBuilder().append(new Rice()).append(new Juice()).append(new FryMeat()).build();
    combo.getCombo().forEach(Edible::eat);
    System.out.println();
    System.out.println("套餐二");
    Combo combo1 = new ComboBuilder().append(new Bread()).append(new Cola()).append(new FriedChicken()).build();
    combo1.getCombo().forEach(Edible::eat);
}
/*output:
套餐一
rice was eaten
juice was drunk
FryMeat was eaten

套餐二
bread was eaten
cola was drunk
friedChicken was eaten
*/
有导演角色的建造者模式

模拟餐厅构建电脑的系统:其中提供ComputerBuilder接口,代表构建电脑的接口。ComputerDirector是电脑导演类,Computer即使电脑实体类,由其中四个部件接口构成。
在这里插入图片描述
电脑实体和其部件接口

@Data//lombok插件,构建属性的get和set方法,toString()等等。
public class Computer {
    private Host host;
    private Keyboard keyboard;
    private Monitor monitor;
    private Mouse mouse;

    public void toUse() {
        host.use();
        keyboard.use();
        monitor.use();
        mouse.use();
    }

}
public interface Host {
    void use();
}
public interface Keyboard {
    void use();
}
public interface Monitor {
    void use();
}
public interface Mouse {
    void use();
}

构建电脑类及其实现,这里使用了lamda表达式实现部件接口

public interface ComputerBuilder {

    void buildHost();

    void buildKeyboard();

    void buildMouse();

    void buildMonitor();

    Computer build();
}
public class HpComputerBuilder implements ComputerBuilder {

    private Computer computer;

    public HpComputerBuilder() {
        computer = new Computer();
    }

    public void buildHost() {
        computer.setHost(() -> System.out.println("hp host used"));
    }

    public void buildKeyboard() {
        computer.setKeyboard(() -> System.out.println("hp keyboard used"));
    }

    public void buildMouse() {
        computer.setMouse(() -> System.out.println("hp mouse used"));
    }

    public void buildMonitor() {
        computer.setMonitor(() -> System.out.println("hp monitor used"));
    }

    public Computer build() {
        return computer;
    }
}
public class HwComputerBuilder implements ComputerBuilder {

    private Computer computer;

    public HwComputerBuilder() {
        computer = new Computer();
    }

    public void buildHost() {
        computer.setHost(() -> System.out.println("hw host used"));
    }

    public void buildKeyboard() {
        computer.setKeyboard(() -> System.out.println("hw keyboard used"));
    }

    public void buildMouse() {
        computer.setMouse(() -> System.out.println("hw mouse used"));
    }

    public void buildMonitor() {
        computer.setMonitor(() -> System.out.println("hw monitor used"));
    }

    public Computer build() {
        return computer;
    }
}

导演类,控制构建的顺序,结构等

public class ComputerDirector {
    public void construct(ComputerBuilder computerBuilder) {
        computerBuilder.buildHost();
        computerBuilder.buildKeyboard();
        computerBuilder.buildMonitor();
        computerBuilder.buildMouse();
    }
}

测试类

public static void main(String[] args) {
    //新建导演对象
    ComputerDirector computerDirector = new ComputerDirector();

    //新建惠普电脑构建对象
    ComputerBuilder hpComputerBuilder = new HpComputerBuilder();
    //导演对象指导惠普构建
    computerDirector.construct(hpComputerBuilder);
    //构建对象构建出电脑
    Computer hpComputer = hpComputerBuilder.build();
    //打印出结果
    hpComputer.toUse();

    System.out.println("----------------------- ");

    //同理构建出华为电脑
    ComputerBuilder hwComputerBuilder = new HwComputerBuilder();
    computerDirector.construct(hwComputerBuilder);
    Computer hwComputer = hwComputerBuilder.build();
    hwComputer.toUse();
}
/*output:
hp host used
hp keyboard used
hp monitor used
hp mouse used
-----------------------
hw host used
hw keyboard used
hw monitor used
hw mouse used
*/

使用场景

  • 需要生成的对象具有复杂的内部结构
  • 一些基本部件不会变,而其组合经常变化的时候(随意组合的建造模式)
  • 关注与零件装配的顺序(有导演角色的建造者模式)

运用

  • jdk的StringBuilder就是经典的随意组合的建造模式
  • lombok中@builder就是对实体类使用随意组合的建造模式
  • protobuf生成出来的java类也是使用随意组合的建造模式

总结

优点:
随意组合的建造模式将构建的细节暴露出来,可以方便组合;有导演角色的建造者模式将构建类抽象,又提供了导演类指导构建过程,使建造者独立,易扩展。
缺点:
对于随意组合的建造模式来说,构建的组合必须受限于组合的元素有共同点;对于有导演角色的建造者模式,当构建的对象内部结构发生变化时,不易扩展。

抽象工厂模式与有导演角色的建造者模式的区别

抽象工厂重点在于构建一系列的产品族,建造者模式重点在于构建出部件组成的整体产品。以上放的电脑举个例子:如果使用抽象工厂模式,重点就是生产主机,键盘,鼠标,显示器等系列产品;如果使用的是建造者模式,重点就是生产由主机,键盘,鼠标,显示器这些部件构成的电脑。

注意:抽象工厂模式与有导演角色的建造者模式对于部件的扩展,或是说产品系列的扩展都是不易扩展的。对于工厂和建造者的扩展时容易扩展的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值