建造者模式
张六儿本是一个钢铁直男,但是由于女朋友小西的耳濡目染和悉心调教,他渐渐的也对女生的化妆品有了很多的了解。日子久了,他也能够替小西挑选化妆品了,小西只要跟张六儿说,她要一个化妆品套装包括:眼影、眉笔和口红,并且说明基本需求,张六儿就能根据需求去商店里给小西购买一套化妆品 。小西不用关心张六儿买化妆品的时候是怎样挑选、比较、试色、搭配的,只需要等着张六儿把一个化妆品套装礼盒送到她面前就好了。
建造者模式同样是一种创建型模式,建造者模式的目的是为了构建一个内部结构较为复杂的对象。使用建造者模式时我们只需要发出相应的指令,不需要关心这个复杂的对象是如何构建而成的,只需要等待建造者将对象建造完毕就可以直接使用了。建造者模式将一个复杂的构建过程与其表示相分离,使得同样的构建过程可以创建不同的表示。
应用场合:在一个系统中,有时一个复杂对象是由很多子对象通过一系列算法构成,各个子对象可能会由于需求的变化而面临着许多改变,但是将它们组合在一起的算法却是相对稳定的。
首先创建一个Category接口表示化妆品的类别,并创建三个类眉笔、眼影、口红分别实现这个接口
public interface Category { String name(); } public class YanYing implements Category{ @Override public String name() { return "眼影"; } } public class MeiBi implements Category{ @Override public String name() { return "眉笔"; } } public class KouHong implements Category{ @Override public String name() { return "口红"; } }
然后创建Item接口表示放入套装中的化妆品,创建YSL口红、香奈儿眼影、植村秀眉笔等等来实现接口
public interface Item { public String getName(); public Category getCategory(); public float getPrice(); } public class MAC_KH implements Item{ @Override public String getName() { return "MAC口红"; } @Override public Category getCategory() { return new KouHong(); } @Override public float getPrice() { return 155.0f; } } public class YSL_KH implements Item{ @Override public String getName() { return "YSL口红"; } @Override public Category getCategory() { return new KouHong(); } @Override public float getPrice() { return 265.0f; } } public class Chanel_YY implements Item{ @Override public String getName() { return "香奈儿眼影"; } @Override public Category getCategory() { return new YanYing(); } @Override public float getPrice() { return 499.0f; } } public class Dior_YY implements Item{ @Override public String getName() { return "Dior眼影"; } @Override public Category getCategory() { return new YanYing(); } @Override public float getPrice() { return 599.0f; } } public class ETUDEHOUSE_MeiBi implements Item{ @Override public String getName() { return "爱丽小屋眉笔"; } @Override public Category getCategory() { return new MeiBi(); } @Override public float getPrice() { return 30.0f; } } public class ShuUemura_MeiBi implements Item{ @Override public String getName() { return "植村秀眉笔"; } @Override public Category getCategory() { return new MeiBi(); } @Override public float getPrice() { return 260.0f; } }
接着创建一个Cosmetics类,表示包装化妆品的礼盒
public class Cosmetics { //用来存放化妆品对象 private ArrayList<Item> suit = new ArrayList<Item>(); //选购化妆品 public void addItem(Item item) { suit.add(item); } //输出总价 public void getCost() { float cost = 0; for(Item c : suit) { cost += c.getPrice(); } System.out.println("共花费¥"+cost); } //展示化妆品 public void showList() { for(Item i : suit) { System.out.println(i.getCategory().name()+":"+i.getName()+",价格为¥"+i.getPrice()); } } }
创建建造者也就是张六儿,负责购买化妆品并包装成套装礼盒。其中包含两个方法,分别表示两种不同的选购方案。
public class Zhang6er { public Cosmetics suit_1() { Cosmetics cos = new Cosmetics(); cos.addItem(new Chanel_YY()); cos.addItem(new MAC_KH()); cos.addItem(new ETUDEHOUSE_MeiBi()); return cos; } public Cosmetics suit_2() { Cosmetics cos = new Cosmetics(); cos.addItem(new Dior_YY()); cos.addItem(new YSL_KH()); cos.addItem(new ShuUemura_MeiBi()); return cos; } }
运行类
public class Main { public static void main(String args[]) { Zhang6er z6 = new Zhang6er(); Cosmetics suit1 = z6.suit_1(); Cosmetics suit2 = z6.suit_2(); System.out.println("张六儿购买的化妆品套装1:"); suit1.showList(); suit1.getCost(); System.out.println("张六儿购买的化妆品套装2:"); suit2.showList(); suit2.getCost(); } }
运行结果:
建造者模式简化了一些复杂对象的创建工作(选购化妆品,做成礼盒),和抽象工厂模式最大的不同是,建造者模式内部的子对象不可以单独创建,只能够创建最终的复杂对象。而抽象工厂模式中,工厂的每个方法都可以创建一个产品族下的某一个特定产品。
优点: 1、建造者独立,易扩展。 2、便于控制细节风险。
缺点: 1、产品必须有共同点,范围有限制(都是化妆品礼盒)。 2、如内部变化复杂,会有很多的建造类(上述例子9个化妆品类)。