美文网首页
(五)建造者模式

(五)建造者模式

作者: feiry | 来源:发表于2019-07-21 15:57 被阅读0次

水果店生意越做越大,竞争力也越来越大,需要进一步吸引人气,那么就推出了套餐

有几个问题:

  1. 套餐包含各类水果的组合,较复杂(套餐后续会越来越复杂)。
  2. 套餐的创建步骤基本固定,设置价格/设置折扣/得到结算价。
  3. 会不断推出新的套餐。

这就需要推出一个业务流程

建造者模式

梳理业务流程

套餐业务流程
将业务流程抽象出来 业务关系图
//创建一个水果套餐Meal类
public class FruitMeal {

    private Apple apple;//苹果--价格
    private Banana banana;//香蕉价格
    private Orange orange;    //桔子价格
    private int discount;//折扣价

    private int totalPrice;//套餐总价

    public void setDiscount(int discount) {
        this.discount = discount;
    }

    public void setApple(Apple apple) {
        this.apple = apple;
    }

    public void setBanana(Banana banana) {
        this.banana = banana;
    }

    public void setOrange(Orange orange) {
        this.orange = orange;
    }

    public int cost(){
        return this.totalPrice;
    }

    public void init() {
        if (null != apple){
            totalPrice += apple.price();
        }
        if (null != orange){
            totalPrice += orange.price();
        }
        if (null != banana){
            totalPrice += banana.price();
        }
        if (totalPrice > 0){
            totalPrice -= discount;
        }
    }

    public void showItems() {
        System.out.println("totalPrice:" + totalPrice);
    }
}
public class HolidayBuilder implements Builder {
    private FruitMeal fruitMeal = new FruitMeal();

    @Override
    public void buildApple(int price) {
        Apple apple = new Apple();
        apple.setPrice(price);
        fruitMeal.setApple(apple);
    }

    @Override
    public void buildBanana(int price) {
        Banana fruit = new Banana();
        fruit.setPrice(price);
        fruitMeal.setBanana(fruit);
    }

    @Override
    public void buildOrange(int price) {
        Orange fruit = new Orange("Peter",80);
        fruit.setPrice(price);
        fruitMeal.setOrange(fruit);
    }

    @Override
    public FruitMeal getFruitMeal() {
        fruitMeal.setDiscount(15);//折扣价格对一个套餐来,是固定的
        fruitMeal.init();
        return fruitMeal;
    }
}
public class FruitMealController {//收银台---导演类

    public void construct() {
//        Builder builder = new HolidayBuilder();
        Builder builder = new OldCustomerBuilder();//spring注入方法,

        //以下代码模板,轻易是不变的
        builder.buildApple(120);//创建苹果设置价格
        builder.buildBanana(80);//创建香蕉设置香蕉价格
        builder.buildOrange(50);//创建桔子设置价格

        FruitMeal fruitMeal = builder.getFruitMeal();


        int cost = fruitMeal.cost();
        System.out.println("本套件花费:"+cost);
    }

    public static void main(String[] args) {
        new FruitMealController().construct();
    }

}

这样就能按照业务流程走了,有点像模板方法模式,Bulider接口其实和工厂方法模式很像

常用的场景

JavaBean对象的构建

  • new对象出来,然后set各种属性
    缺点:必须得对象构建完成后,才能set属性值,中间可以插入其他操作(可以看成非原子操作)
  • 把所有属性作为构造器的入参
    缺点:属性越多,构造器参数越多
public class Example<T> {
    private T foo;
    private String bar;

    public Example() {
    }

    public Example(T foo, String bar) {
        this.foo = foo;
        this.bar = bar;
    }

    public T getFoo() {
        return foo;
    }

    public void setFoo(T foo) {
        this.foo = foo;
    }

    public String getBar() {
        return bar;
    }

    public void setBar(String bar) {
        this.bar = bar;
    }
}

lombok有提供builder模式的注解

@Builder
public class Example<T> {
    private T foo;
    private String bar;
}

等同于

class Example<T> {
    private T foo;
    private String bar;
    
    private Example(T foo, String bar) {
        this.foo = foo;
        this.bar = bar;
    }
    
    public static <T> ExampleBuilder<T> builder() {
        return new ExampleBuilder<T>();
    }
    
    public static class ExampleBuilder<T> {
        private T foo;
        private String bar;
        
        private ExampleBuilder() {}
        
        public ExampleBuilder foo(T foo) {
            this.foo = foo;
            return this;
        }
        
        public ExampleBuilder bar(String bar) {
            this.bar = bar;
            return this;
        }
        
        @java.lang.Override public String toString() {
            return "ExampleBuilder(foo = " + foo + ", bar = " + bar + ")";
        }
        
        public Example build() {
            return new Example(foo, bar);
        }
    }
   }

使用方法如下

@Builder
public class Example<T> {
    private T foo;
    private String bar;

    public static void main(String[] args) {
        ExampleBuilder<String> builder = Example.builder();//获取对象的建造者
        Example<String> build = builder.bar("1")
                .foo("2")
                .build();//链式构建对象
        System.out.println(build);
    }
}

这种Builder模式构建Bean对象的好处是

  1. 在调用build()方法之前是不会创建出对象的,传统set方法,是先创建对象,再设置值
    builder模式是先设置值,后创建对象。
    这两者的区别是,传统set方法因为对象已经创建出来了,所以可以对对象做其他操作(如get属性值),
    而build方法对象一创建出来就是设置好值的对象,这时候去获取属性值不会是null
  2. 链式调用,传统set方法返回值是void,而且@Builder返回该对象的引用,这样设置值的时候,就不用一遍遍复制引用变量,然后点一下方法名,可以直接点出方法,使用更加优雅

相关文章

  • 创建型模式:建造者模式

    个人公众号原文:创建型模式:建造者模式 五大创建型模式之四:建造者模式。 简介 姓名 :建造者模式 英文名 :Bu...

  • Builder Pattern in Java

    建造者模式:建造者模式定义建造者模式应用场景实现案例Jdk中的建造者模式建造者模式的优点建造者模式的缺点 建造者模...

  • 设计模式(4) 建造者模式

    什么是建造者模式 经典建造者模式的优缺点 对建造者模式的扩展 什么是建造者模式 建造者模式将一个复杂的对象的构建与...

  • 建造者模式(部件构造)

    目录 建造者模式的理念 从 POJO 到建造者模式的思考 怎么来实现建造者模式 建造者模式在Android源码中的...

  • 五 建造者模式

    本文主要介绍创建型模式的最后一种————建造者模式。 概念 建造者模式(英:Builder Pattern)是一种...

  • (五)建造者模式

    水果店生意越做越大,竞争力也越来越大,需要进一步吸引人气,那么就推出了套餐 有几个问题: 套餐包含各类水果的组合,...

  • 【设计模式】之建造者Builder模式

    建造者模式 什么是建造者模式? 建造者模式属于创建型模式的一员,可以控制对象的实例化过程。建造者模式简化了复杂对象...

  • 建造者模式

    一、建造者模式介绍 二、建造者模式代码实例

  • 建造者模式

    建造者模式 首先,建造者模式的封装性很好。使用建造者模式可以有效的封装变化,在使用建造者模式的场景中,一般产品类和...

  • 建造者模式:深入理解建造者模式 ——组装复杂的实例

    目录: 一 建造者模式介绍 1.1 定义 1.2 为什么要用建造者模式(优点)? 1.3 哪些情况不要用建造者模式...

网友评论

      本文标题:(五)建造者模式

      本文链接:https://www.haomeiwen.com/subject/frbmlctx.html