建造者模式
使用多个简单的对象一步一步构建成一个复杂的对象。
我们假设一个快餐店的商业案例,其中,一个典型的套餐可以是一个汉堡(Burger)和一杯冷饮(Cold drink)。汉堡(Burger)可以是素食汉堡(Veg Burger)或鸡肉汉堡(Chicken Burger),它们是包在纸盒中。冷饮(Cold drink)可以是可口可乐(coke)或百事可乐(pepsi),它们是装在瓶子中。
我们将创建一个表示食物条目(比如汉堡和冷饮)的 Item 接口和实现 Item 接口的实体类,以及一个表示食物包装的 Packing 接口和实现 Packing 接口的实体类,汉堡是包在纸盒中,冷饮是装在瓶子中。
然后我们创建一个 Meal 类,带有 Item 的 ArrayList 和一个通过结合 Item 来创建不同类型的 Meal 对象的 MealBuilder。BuilderPatternDemo,我们的演示类使用 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());
}