设计模式 建造者/原型模式

建造者模式

使用多个简单的对象一步一步构建成一个复杂的对象。

 

我们假设一个快餐店的商业案例,其中,一个典型的套餐可以是一个汉堡(Burger)和一杯冷饮(Cold drink)。汉堡(Burger)可以是素食汉堡(Veg Burger)或鸡肉汉堡(Chicken Burger),它们是包在纸盒中。冷饮(Cold drink)可以是可口可乐(coke)或百事可乐(pepsi),它们是装在瓶子中。

我们将创建一个表示食物条目(比如汉堡和冷饮)的 Item 接口和实现 Item 接口的实体类,以及一个表示食物包装的 Packing 接口和实现 Packing 接口的实体类,汉堡是包在纸盒中,冷饮是装在瓶子中。

然后我们创建一个 Meal 类,带有 Item 的 ArrayList 和一个通过结合 Item 来创建不同类型的 Meal 对象的 MealBuilderBuilderPatternDemo,我们的演示类使用 MealBuilder 来创建一个 Meal

 

步骤1,创建表示事物条目和事物包装的接口。

食物条目Item接口

public interface Item {
    public String name();
    public Packing packing();
    public float price();
}

食物包装接口

public interface Packing {
    public String pack();
}

 

 

步骤2 创建实现Packing接口的实体类(包装方法,纸包装或瓶子)

用纸包装的packing实现类

public class Wrapper implements Packing {
    @Override
    public String pack() {
        return "Wrapper";
    }
}

 

  用瓶子包装的packing实现类

public class Bottle implements Packing {
    @Override
    public String pack() {
        return "Bottle";
    }
}

 

 

 

步骤3实现食物条目的抽象类(2种食物,即汉堡和可乐)

 实现食物条目录的抽象类  汉堡的  包装方法以及价格

public abstract class Burger implements Item {
    @Override
    public Packing packing() {
        return new Wrapper();
    }
    @Override
    public abstract float price();
}

 

可乐的实现抽象类  瓶子和价格

public abstract class ColdDrink implements Item {
    @Override
    public Packing packing() {
        return new Bottle();
    }
    @Override
    public abstract float price();
}

 

 

 

步骤4 扩展抽象类(完成每一种食物的子类的实现类)

 

鸡肉汉堡实现类。

public class ChickenBurger extends Burger {
    @Override
    public String name() {
        return "Chicken Burger";
    }
    @Override
    public float price() {
        return 50.0f;
    }
}

 

素食汉堡实现类

public class VegBurger extends Burger {
    @Override
    public String name() {
        return "Veg Burger";
    }

    @Override
    public float price() {
        return 25.0f;
    }
}

 

   可口可乐实现类

public class Coke extends ColdDrink {
    @Override
    public String name() {
        return "Coke";
    }
    @Override
    public float price() {
        return 30.0f;
    }
}

 

百事可乐实现类

public class Pepsi extends ColdDrink {
    @Override
    public String name() {
        return "Pepsi";
    }
    @Override
    public float price() {
        return 35.0f;
    }
}

 

 

 

步骤5创建一个Meal类

创建一个食物目录条创建类,套餐创建

public class Meal {
    private List<Item> items = new ArrayList<>();
    public void addIten(Item item){
        items.add(item);
    }
    public float getCost(){
        float cost = 0.0f;
        for (Item item: items){
            cost += item.price();
        }
        return cost;
    }
    public void showItems(){
        for (Item item:items){
            System.out.println("Item : "+item.name());;
            System.out.println(", Packing : "+item.packing().pack());
            System.out.println(", Price : "+item.price());
        }
    }
}

 

 

 

 

步骤6 创建一个MealBuilder类,builder类负责创建Meal对象

用来创建套餐的搭配

public class MealBuilder {
     public  Meal prepareVegMeal(){
         Meal  meal=new Meal();
         meal.addIten(new VegBurger());
         meal.addIten(new Coke());
         return meal;
     }
     public Meal preapareNonVegMeal(){
         Meal meal = new Meal();
         meal.addIten(new ChickenBurger());
         meal.addIten(new Pepsi());
         return meal;
     }
}

 

 

 

步骤7 使用

public class BuilderPartternDemo {
    public static void main(String[] args) {
        MealBuilder mealBuilder = new MealBuilder();

        Meal vegMeal =mealBuilder.prepareVegMeal();
        System.out.println("Veg Meal");
        vegMeal.showItems();
        System.out.println("Total Cost : "+vegMeal.getCost());

        Meal nonVegMeal = mealBuilder.preapareNonVegMeal();
        System.out.println("\n\nNon-Veg Meal");
        nonVegMeal.showItems();
        System.out.println("Total Cost: "+nonVegMeal.getCost());
    }
}

 

 

 

 

 

原型模式(Prototype Pattern)

用于创建重复的对象,同时又能保证性能。

实现一个原型接口,该接口用于创建当前对象的克隆。当创建对象代价较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库实现操作之后被创建。我们可以缓存该对象,在下一个请求返回它的克隆,在需要是更新数据库,以此来减少数据库调用。

 

 

步骤1

实现 Cloneable接口

public abstract class Shape implements Cloneable{
    private String id;
    protected  String type;
    abstract void draw();
    public String getType(){ return type; }
    public String getId(){ return id; }
    public void setId(String id){this.id=id; }
    public Object clone(){
        Object clone = null;
        try{
            clone = super.clone();
        }catch (CloneNotSupportedException e){
            e.printStackTrace(); }
        return clone;}
}

 

 

 

步骤2

扩展抽象类的实体类(2个)

 

public class Rectangle extends Shape {
    @Override
    void draw() { System.out.println("Inside Rectangle::draw() method"); }
    public Rectangle(){ type="Rectangle";}
}

 

 

public class Square extends Shape {
    @Override
    void draw() {System.out.println("Inside Square :: draw() method ");}
    public Square(){type="Square";}
}

 

 

 

 

步骤3

创建一个类,从数据库获取实体类,并把它们存储在一个Hashtable中

 

public class ShapeCache {
    private static Hashtable<String,Shape>

shapeMapl=new Hashtable<String, Shape>();

    public static Shape getShape(String shapeId){
        Shape cachedShape=shapeMapl.get(shapeId);
        return (Shape) cachedShape.clone();
    }

    //对每种形状都运行数据库查询,并创建该形状
    //shapeMap.put(shapeKey,shape)
    //例如,我们要添加形状
    public static void  loadCache(){
        Square square = new Square();
        square.setId("1");
        shapeMapl.put(square.getId(),square);

        Rectangle rectangle= new Rectangle();
        rectangle.setId("2");
        shapeMapl.put(rectangle.getId(),rectangle);
    }
}

 

 

 

 

步骤4 使用

 

public static void main(String[] args) {
    ShapeCache.loadCache();
    Shape clonedShape = (Shape) ShapeCache.getShape("1");
    System.out.println("Shape :"+clonedShape.getType());

    Shape clonedShape1 = ShapeCache.getShape("2");
    System.out.println(" Shape : "+clonedShape.getType());

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值