理解装饰模式

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 }

 

你可能感兴趣的:(装饰模式)