装饰者模式

      装饰模式指的是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。

比如我们在买饼的这个场景里,就可以使用装饰者模式。我们可以只买一个饼(pie)手抓饼或鸡蛋饼,可以什么都不加,可以加鸡蛋(egg),培根(bacanic),生菜(lettuce),火腿肠(sausage)等等。在这里饼是需要装饰的对象,而鸡蛋等则是装饰品。

我们看一下装饰者模式的图例

 component:公共组件,装饰品和装饰对象都继承于此。

 concreteComponent:需要装饰的对象,扩展与component。

 decorator:装饰品共同实现的接口,也可是抽象类。

 concreteDecorator:装饰品,包含着一个component实例变量。

 

现在我们根据上面的图例来实现买手抓饼的场景。

首先定义component组件food类。

package sjms.decorator;

/**
 * component
 * @author dwl
 *
 */
public abstract class Food {
	
	//描述
	String desc = "";
	//返回描述
	public String getDesc() {
		return desc;
	}
	//计算价格,在子类中实现
	public abstract double cost();

}

再定义装饰对象的Pie类。

package sjms.decorator;

/**
 * concreteComponent
 * 手抓饼
 * @author dwl
 *
 */
public class HandPie extends Food {
	
	
	public HandPie() {
		desc = "手抓饼";
	}

	//一个饼3元
	@Override
	public double cost() {
		return 3.00;
	}

}

 

package sjms.decorator;

/**
 * concreteComponent
 * 鸡蛋饼
 * @author dwl
 *
 */
public class EggPie extends Food {
	
	
	public EggPie() {
		desc = "鸡蛋饼";
	}

	//一个饼2.5元
	@Override
	public double cost() {
		return 2.50;
	}

}

配料的公共父类。

package sjms.decorator;

/**
 * decorator
 * 配料的抽象类,所有配料继承于此
 * @author dwl
 *
 */
public abstract class Condiment extends Food {
	
	//子类重新实现该方法
	public abstract String getDesc();

}

最后我们来写具体的配料鸡蛋生菜等。

package sjms.decorator;

/**
 * concreteDecorator
 * 鸡蛋
 * @author dwl
 *
 */
public class Egg extends Condiment {
	
	//被装饰者
	Food food;
	
	public Egg(Food food){
		this.food = food;
	}

	@Override
	public String getDesc() {
		return food.getDesc()+",鸡蛋";
	}
	
	
	//鸡蛋的价格加上被装饰者的价格
	@Override
	public double cost() {
		return 1.00 + food.cost();
	}

}
package sjms.decorator;

/**
 * concreteDecorator
 * 生菜
 * @author dwl
 *
 */
public class Lettuce extends Condiment {
	
	//被装饰者
	Food food;
	
	public Lettuce(Food food){
		this.food = food;
	}

	@Override
	public String getDesc() {
		return food.getDesc()+",生菜";
	}
	
	
	//生菜的价格加上被装饰者的价格
	@Override
	public double cost() {
		return 1.50 + food.cost();
	}

}
package sjms.decorator;

/**
 * concreteDecorator
 * 培根
 * @author dwl
 *
 */
public class Bacanic extends Condiment {
	
	//被装饰者
	Food food;
	
	public Bacanic(Food food){
		this.food = food;
	}

	@Override
	public String getDesc() {
		return food.getDesc()+",培根";
	}
	
	
	//培根的价格加上被装饰者的价格
	@Override
	public double cost() {
		return 2.00 + food.cost();
	}

}

装饰对象和装饰品都实现了,我们现在来看看买一个手抓饼加鸡蛋生菜培根怎么实现。

package sjms.decorator;

/**
 * 买一个饼
 * @author dwl
 *
 */
public class BuyPie {

	public static void main(String[] args) {
		//老板,买一个手抓饼
		Food pie = new HandPie();
		System.out.println(pie.getDesc()+","+pie.cost()+"元");
		
		//加一个鸡蛋吧
		Food agg = new Egg(pie);
		System.out.println(agg.getDesc()+","+agg.cost()+"元");
		
		//加上生菜,营养均衡
		Food lettuce = new Lettuce(agg);
		System.out.println(lettuce.getDesc()+","+lettuce.cost()+"元");
		
		//再加上培根,我喜欢吃肉
		Food bacanic = new Bacanic(lettuce);
		System.out.println(bacanic.getDesc()+","+bacanic.cost()+"元");
		
	}

}

来看看控制台输出的结果。

 总结:装饰者模式——利用对象组合,动态的将责任附加到对象上,扩展一个对象的功能。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值