设计模式:装饰者模式( 二 )


所以,我们要把实现类分为两类,一种实现类时调料,其有一个成员变量就是基类的一个对象 。另一个实现类就是面的种类:牛肉面、哨子面 。
我在书上的图,作了一些额外的说明 。如下:

设计模式:装饰者模式

文章插图
另外书上也给了饮料的图,更为简单和清晰些:
设计模式:装饰者模式

文章插图
代码
实际上我还是觉得代码描述的更为清楚:
设计模式:装饰者模式

文章插图
public class TestMain {public static void main(String[] args) {//普通牛肉面Noodle beefNoodle = new BeefNoodle();System.out.println(beefNoodle.getDescription() + ":" + beefNoodle.cost());//普通猪肉面Noodle porkNoodle = new PorkNoodle();System.out.println(porkNoodle.getDescription() + ":" + porkNoodle.cost());//加了鸡蛋的牛肉面Noodle beefNoodle2 = new BeefNoodle();beefNoodle2 = new EggCondiment(beefNoodle2);System.out.println(beefNoodle2.getDescription() + ":" + beefNoodle2.cost());//加了鸡蛋和丸子的猪肉面Noodle porkNoodle2 = new PorkNoodle();porkNoodle2 = new EggCondiment(porkNoodle2);porkNoodle2 = new MeatballCondiment(porkNoodle2);System.out.println(porkNoodle2.getDescription() + ":" + porkNoodle2.cost());}}
/*** 这是一个面的基类 。所以面的种类的实现类和调料的装饰类都必须继承这个类 。* @author zy**/public abstract class Noodle {String description = "unknown noodle";public String getDescription(){return description;}public abstract double cost();}
设计模式:装饰者模式

文章插图
public class BeefNoodle extends Noodle {public BeefNoodle() {// TODO Auto-generated constructor stubdescription = "牛肉面";}@Overridepublic double cost() {return 10;//表示这个碗牛肉面10元,当然可以做的更专业一些,用个字段来设置 。}}
public class PorkNoodle extends Noodle {public PorkNoodle() {// TODO Auto-generated constructor stubdescription = "猪肉面";}@Overridepublic double cost() {// TODO Auto-generated method stubreturn 7;}}
public abstract class CondimenDecorator extends Noodle {/*** 用于装饰的实现类必须有一个成员变量就是要装饰的对象 。在这里就是面* 使用Noodle这个基类的原因除了一般的表示种类的面* 用于装饰的实现类,还可以再次被装饰* 有点像加鸡蛋、加丸子的牛肉面* 被装饰了两次* * 此外,书上讲这个成员变量写在了每一个实现类里面,难道不能写在这个父类里面么?* 试试看 。*/Noodle noodle;/*** 所以调料必须实现这个方法,这样才能知道这个面的具体描述* 比如 加鸡蛋的牛肉面*/public abstract String getDescription();}
public class EggCondiment extends CondimenDecorator {public EggCondiment(Noodle noodle) {// TODO Auto-generated constructor stubthis.noodle = noodle;}@Overridepublic String getDescription() {// TODO Auto-generated method stubreturn noodle.getDescription() + "加鸡蛋";}@Overridepublic double cost() {// TODO Auto-generated method stubreturn noodle.cost() + 1;}}
public class MeatballCondiment extends CondimenDecorator {public MeatballCondiment(Noodle noodle) {// TODO Auto-generated constructor stubthis.noodle = noodle;}@Overridepublic String getDescription() {// TODO Auto-generated method stubreturn noodle.getDescription() + "加肉丸";}@Overridepublic double cost() {// TODO Auto-generated method stubreturn noodle.cost() + 2;}}