建造者模式
建造者模式适用于将多个简单的对象合并成一个复杂的对象。
应用场景
当系统中有许多相对固定的对象,而他们需要组合成一个复杂的对象,其组合方式又不确定的时候,使用建造者模式可以降低复杂度。
实例
以中国移动的4G飞享套餐为例,自选套餐包括流量和语音,如下图所示:
首先,我们创建一个接口,表示套餐中的一项。
/** * 套餐中的一项 */ public interface Item { public String name();//名称 public float price();//价格 public int amount();//数量 public String unit();//单位 }
然后,我们创建语音抽象类实现该接口。
/** * 语音抽象类,实现Item */ public abstract class Voice implements Item { @Override public String name() { return "语音"; } @Override public String unit() { return "分钟"; } public abstract float price(); public abstract int amount(); }
具体的语音类:
/** * 语音类 */ public class Voice18 extends Voice { @Override public float price(){ return 18.0f; } @Override public int amount(){ return 50; } } public class Voice28 extends Voice { @Override public float price(){ return 28.0f; } @Override public int amount(){ return 100; } } public class Voice48 extends Voice { @Override public float price(){ return 48.0f; } @Override public int amount(){ return 220; } }
接下来,创建流量的抽象类:
public abstract class Flow implements Item { @Override public String name() { return "流量"; } @Override public String unit() { return "M"; } public abstract float price(); public abstract int amount(); }
流量的具体类:
public class Flow20 extends Flow { @Override public float price(){ return 20.0f; } @Override public int amount(){ return 300; } } public class Flow30 extends Flow { @Override public float price(){ return 30.0f; } @Override public int amount(){ return 500; } } public class Flow40 extends Flow { @Override public float price(){ return 40.0f; } @Override public int amount(){ return 700; } }
套餐类:
public class Package { private List<Item> items=new ArrayList<Item>(); public String name; public void addItem(Item item){ items.add(item); } public float getTotalPrice(){ float price=0.0f; for (Item item:items){ price+=item.price(); } return price; } public void printItems(){ System.out.println(this.name+"包括:"); for(Item item:items){ System.out.println(item.name()+item.amount()+item.unit()); } System.out.println("价格:"+this.getTotalPrice()); } }
最后是建造者类,在该类中可以创建不同的套餐:
public class Builder { public Package preparePackage38(){ Package p=new Package(); p.addItem(new Voice18()); p.addItem(new Flow20()); p.name="38元套餐"; return p; } }
执行代码:
Builder builder=new Builder(); builder.preparePackage38().printItems();
结果:
38元套餐包括:
语音50分钟
流量300M
价格:38.0