美文网首页
建造者模式

建造者模式

作者: 慎独静思 | 来源:发表于2022-12-01 07:42 被阅读0次

    将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
    它使用多个简单的对象一步一步构建成一个复杂的对象,复杂对象通常由各个部分的子对象用一定的算法构成,当各个部分可能经常变化,但组合它们的算法确相对稳定时可以考虑使用建造者模式。

    建造者模式

    上图中我们创建了一个复杂对象,复杂对象是由两个简单对象构成的,组成复杂对象的简单对象可能经常变化,但组合它们的算法,也就是Builder对象是相对稳定的,此时可以考虑使用建造者模式。

    咱们还是用抽象工厂模式 中提到的早餐的例子来说明

    interface Item {
        float getPrice();
    }
    
    interface Drinks extends Item {
        void drink();
    }
    
    class Soybean implements Drinks {
    
        @Override
        public void drink() {
            System.out.println("drink Soybean");
        }
    
        @Override
        public float getPrice() {
            return 1.5f;
        }
    }
    
    class Milk implements Drinks {
    
        @Override
        public void drink() {
            System.out.println("drink milk");
        }
    
        @Override
        public float getPrice() {
            return 2f;
        }
    }
    
    interface Pasta extends Item {
        void eat();
    }
    
    class YouTiao implements Pasta {
    
        @Override
        public void eat() {
            System.out.println("eat you tiao");
        }
    
        @Override
        public float getPrice() {
            return 1f;
        }
    }
    
    class Bread implements Pasta {
    
        @Override
        public void eat() {
            System.out.println("eat bread");
        }
    
        @Override
        public float getPrice() {
            return 2.5f;
        }
    }
    

    以上内容是我们创建的simple item

    interface Meal {
        void orderItem(Item item);
    
        float getCost();
    }
    
    class Breakfast implements Meal {
    
        private List<Item> items = new ArrayList<>();
    
        @Override
        public void orderItem(Item item) {
            items.add(item);
        }
    
        @Override
        public float getCost() {
            float result = 0f;
            for (Item item: items) {
                result += item.getPrice();
            }
            return result;
        }
    }
    

    这是我们创建的早餐类,它是个复杂对象

    interface MealBuilder {
        void startOrder();
        Meal getMeal();
    }
    
    class BreakfastBuilder implements MealBuilder {
    
        private Meal meal;
    
        @Override
        public void startOrder() {
            meal = new Breakfast();
        }
    
        public void orderSoybean(int count) {
            Objects.requireNonNull(meal);
            for (int i = 0; i < count; i++) {
                meal.orderItem(new Soybean());
            }
        }
    
        public void orderMilk(int count) {
            Objects.requireNonNull(meal);
            for (int i = 0; i < count; i++) {
                meal.orderItem(new Milk());
            }
        }
    
        public void orderYouTiao(int count) {
            Objects.requireNonNull(meal);
            for (int i = 0; i < count; i++) {
                meal.orderItem(new YouTiao());
            }
        }
    
        public void orderBread(int count) {
            Objects.requireNonNull(meal);
            for (int i = 0; i < count; i++) {
                meal.orderItem(new Bread());
            }
        }
    
        @Override
        public Meal getMeal() {
            return meal;
        }
    }
    

    这是我们创建的builder,它用来创建复杂对象。

            BreakfastBuilder mealBuilder = new BreakfastBuilder();
            mealBuilder.startOrder();
            mealBuilder.orderSoybean(2);
            mealBuilder.orderYouTiao(3);
            mealBuilder.orderBread(2);
    
            Meal meal = mealBuilder.getMeal();
            System.out.println("Price is " + meal.getCost());
    

    这是客户端使用builder创建meal的过程,builder隐藏了创建复杂对象的细节,给客户提供了方便调用的接口。
    标准的使用过程中还存在一个Director角色,用来构建建造者,此处未使用。

    平时我们比较常用的是链式调用的建造者模式。

    class Breakfast implements Meal {
    
        private List<Item> items = new ArrayList<>();
    
        public Breakfast(Builder builder) {
            items.addAll(builder.items);
        }
    
        @Override
        public void orderItem(Item item) {
            items.add(item);
        }
    
        @Override
        public float getCost() {
            float result = 0f;
            for (Item item : items) {
                result += item.getPrice();
            }
            return result;
        }
    
        public static class Builder {
            private List<Item> items = new ArrayList<>();
    
            public Builder orderSoybean(int count) {
                for (int i = 0; i < count; i++) {
                    items.add(new Soybean());
                }
    
                return this;
            }
    
            public Builder orderMilk(int count) {
                for (int i = 0; i < count; i++) {
                    items.add(new Milk());
                }
    
                return this;
            }
    
            public Builder orderYouTiao(int count) {
                for (int i = 0; i < count; i++) {
                    items.add(new YouTiao());
                }
    
                return this;
            }
    
            public Builder orderBread(int count) {
                for (int i = 0; i < count; i++) {
                    items.add(new Bread());
                }
    
                return this;
            }
    
            public Breakfast build() {
                return new Breakfast(this);
            }
        }
    }
    

    我们以链式调用的方式重写了上边的例子。

            Meal breakfast = new Breakfast.Builder()
                    .orderSoybean(2)
                    .orderBread(3)
                    .orderYouTiao(2)
                    .build();
    
            System.out.println("Price is: " + breakfast.getCost());
    

    直观上来说,感觉链式调用的方式更容易理解和使用,可能是因为平时接触的最多的还是链式调用的构建者模式。

    看了一遍又写了一遍,感觉还是一知半解,悲
    可能脑海中有这个印象了吧,遇到问题可以朝这个方向考虑。
    完结。

    参考
    《设计模式-可复用面向对象软件的基础》

    相关文章

      网友评论

          本文标题:建造者模式

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