理解装饰模式
Lucene的分词器中使用了装饰模式,之前不太理解,今天花点时间消化一下。
定义:装饰模式允许程序动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
UML图

举个例子:
假如你是卖手抓饼的,你卖两种手抓饼,大号和小号,同时买家可以随意加生菜,鸡蛋,火腿肠,培根等。
如果用继承,想想有多麻烦。这时装饰模式就派上用场了,代码如下:
1 public class Program { 2 3 /** 4 * @param args 5 */ 6 public static void main(String[] args) { 7 8 // 路人甲 9 Program p1 = new Program(); 10 // 购买大号手抓饼 11 Pastry pastry = p1.new BigPastry(); 12 // 加生菜(生菜修饰手抓饼) 13 Pastry lettuce = p1.new Lettuce(pastry); 14 // 加培根(培根修饰加了生菜的手抓饼) 15 Pastry bacon = p1.new Bacon(lettuce); 16 17 System.out.println("路人甲买饼"); 18 System.out.println(bacon.getName()); 19 System.out.println(bacon.getPrice()); 20 System.err.println("***********"); 21 22 // 路人乙 23 Program p2 = new Program(); 24 // 购买小号手抓饼 25 pastry = p1.new SmallPastry(); 26 // 加蛋(鸡蛋修饰小号手抓饼) 27 Pastry egg = p2.new Egg(pastry); 28 // 加生菜(生菜修饰加蛋的手抓饼) 29 lettuce = p2.new Lettuce(egg); 30 // 加培根(培根修饰加了蛋和生菜的手抓饼) 31 bacon = p2.new Bacon(lettuce); 32 33 System.out.println("路人乙买饼"); 34 System.out.println(bacon.getName()); 35 System.out.println(bacon.getPrice()); 36 37 } 38 39 /** 40 * 41 * 手抓饼 42 * 43 */ 44 public abstract class Pastry { 45 46 protected String name; 47 48 public String getName() { 49 return name; 50 } 51 52 protected double price; 53 54 public abstract double getPrice(); 55 } 56 57 /** 58 * 59 * 附加物 60 * 61 */ 62 public abstract class Attachment extends Pastry { 63 64 protected Pastry pastry; 65 66 public Attachment(Pastry pastry) { 67 this.pastry = pastry; 68 } 69 70 @Override 71 public double getPrice() { 72 return pastry.getPrice() + price; 73 } 74 75 } 76 77 /** 78 * 79 * 大号手抓饼,5元一个 80 * 81 */ 82 public class BigPastry extends Pastry { 83 84 public BigPastry() { 85 name = "大号手抓饼(5元) "; 86 } 87 88 @Override 89 public double getPrice() { 90 return 5.0; 91 } 92 93 } 94 95 /** 96 * 97 * 小号手抓饼,3元一个 98 * 99 */ 100 public class SmallPastry extends Pastry { 101 102 public SmallPastry() { 103 name = "小号手抓饼(3元) "; 104 } 105 106 @Override 107 public double getPrice() { 108 return 3.0; 109 } 110 111 } 112 113 /** 114 * 115 * 生菜5毛 116 * 117 */ 118 public class Lettuce extends Attachment { 119 120 public Lettuce(Pastry pastry) { 121 super(pastry); 122 price = 0.5; 123 name = pastry.getName() + " 生菜(5毛),"; 124 } 125 126 } 127 128 /** 129 * 130 * 火腿肠1元 131 * 132 */ 133 public class Ham extends Attachment { 134 135 public Ham(Pastry pastry) { 136 super(pastry); 137 price = 1.0; 138 name = pastry.getName() + "火腿肠(1元),"; 139 } 140 } 141 142 /** 143 * 144 * 培根2元 145 * 146 */ 147 public class Bacon extends Attachment { 148 149 public Bacon(Pastry pastry) { 150 super(pastry); 151 price = 2.0; 152 name = pastry.getName() + "培根(2元),"; 153 } 154 155 } 156 157 /** 158 * 159 * 鸡蛋1元 160 * 161 */ 162 public class Egg extends Attachment { 163 164 public Egg(Pastry pastry) { 165 super(pastry); 166 price = 1.0; 167 name = pastry.getName() + "鸡蛋(1元),"; 168 } 169 170 } 171 172 }

浙公网安备 33010602011771号