初探《Head First 设计模式》 ----装饰者模式

一、概念

    装饰者模式是通过动态的将责任添加到对象身上。若要扩展能力,装饰者模式是比继承更具有弹性的替代方案。

    个人理解:

   《Head First 设计模式》书中有直接讲解,装饰者模式是通过对象实例进行增强,是运行时组装。继承是通过扩展新类实现增强,是编译时、是静态的。

  故事说明(虚构),

  广告公司准备 IPhone 7广告语,增强广告语 “IPhone 7是一款手机”。添加4G快速联网等标语。并且打印10w张。

  继承方式工作:直接打印10w张“IPhone 7 是具有4G快速联网功能的手机。”广告语。交给 A粘贴去宣传。

  装饰者模式工作:分别打印  “IPhone 7 是一款手机” ,“具有”,“4G快速联网”,“的功能”。等短语10w张。 让A 在粘贴的时,组装成“IPhone 7 是一款手机,具有4G快速联网等功能。” 的广告语宣传。

  好了继承方式,装饰者模式都完成打印工作了。准备宣传的时候,甲方要求说,要添加“后置摄像1200万像素”的标语,让广告公司增加这个功能。

 解决方案:

继承方式:重新打印10w张“IPhone 7 是具有后置摄像1200万像素、4G快速联网功能的手机。

装饰者模式:打印10w张“后置摄像1200万像素、”短语,加上原来的短语,宣传拼接成广告语。

      由例子可以看出。我们增强广告语时,继承方式,需要通过不断的重新对广告语编写实现增强。装饰者是通过不断的添加新的属性,灵活组装的完成广告语的增强。可见装饰者是更具有弹性的方式增强。

       进一步假设,XXX手机也出了一部手机。也要4G快速联网、后置摄像1200万像素标语。是不是说,其实IPhone 7也应该是可通过组装的。

二、设计原则

   开发-关闭原则,类应该对类扩展开放,对修改关闭。

   找出应用中的变化之处,对立出来,拒绝和不变的代码混在一起。

三、代码实现

/**
 * 此处实现装饰者模式,通过短语的方式装饰“IPhon7 是一台手机”.
 * @author zhuang
 *
 */


/**
 * 广告标语
 * @author zhuang
 *
 */
public abstract class Slogan {
	
	public abstract String toString();
	
}


/**
 * IPhon 7 被修饰广告语
 * @author zhuang
 *
 */
public class IPhone7Slogan extends Slogan {
	
	@Override
	public String toString() {	
		return "IPhone7 是一款手机";
	}
}



/**
 * 短语条件装饰 
 * 设计原则 :变化之处,对立出来,拒绝和不变的代码混在一起。
 *  统一实现toString, 变化的内容成为短语,交由子类诠释。
 * @author zhuang
 *
 */
abstract class PhraseDecorator extends Slogan {
	
	/**
	 * 装饰对象
	 */
	protected Slogan slogan ;
	
	public PhraseDecorator(Slogan slogan) {
		this.slogan = slogan;
	}
	
	/**
	 * 统一实现
	 */
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return slogan.toString() + getPhrase();
	}
	
	/**
	 * 这是变化,不同的短语是装饰过程中的变化之处
	 * @return
	 */
	public abstract String getPhrase();

}

/**
 * 1200w后置摄像头
 * @author zhuang
 *
 */
public class RearCamera1200 extends PhraseDecorator{
	
	public RearCamera1200(Slogan slogan) {
		super(slogan);
	}

	@Override
	public String getPhrase() {
		// TODO Auto-generated method stub
		return "1200w后置摄像头";
	}
}

/**
 * 4G联网
 * @author zhuang
 *
 */
public class Net4G extends PhraseDecorator {

	
	public Net4G(Slogan slogan) {
		super(slogan);
	}

	
	@Override
	public String getPhrase() {
		// TODO Auto-generated method stub
		return "4G联网";
	}

}

/**
 * 辅助修饰
 * @author zhuang
 *
 */
public class AssistDecorator extends Slogan {
	
	private String append ;
	
	private Slogan slogan;

	public AssistDecorator(Slogan slogan,String append) {
		this.slogan = slogan;
		this.append = append;
	}

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return append == null || append.length() ==0 ?  slogan.toString()
				: slogan.toString()+append;
	}

}


// ---------------------------測試----------------------------------------

public class DecoratorPatternTest {

	public static void main(String[] args) {
		
		//最简单的广告语
		Slogan slogan = new IPhone7Slogan();
		System.out.println("最简单的广告语: "+slogan.toString()); //最简单的广告语
		
		// 粗超增强版广告语
		Slogan slogan2 = new IPhone7Slogan();
		slogan2 = new Net4G(new RearCamera1200(slogan2));
		System.out.println("粗糙版的广告语: "+slogan2.toString()); 
		
		// 精细版增强广告语
		Slogan slogan3 = new IPhone7Slogan();
		slogan3 = new AssistDecorator(slogan3, "具有");
		slogan3 = new AssistDecorator(new RearCamera1200(slogan3), "、");
		slogan3 = new AssistDecorator(new Net4G(slogan3),"的功能");
		System.out.println("增强的广告语: "+slogan3.toString()); //最简单的广告语
		
	}
}





四、測試結果

五、总结

       装饰者模式在功能增强的弹性上确实优于继承,动态组装,满足开发-关闭原则(很重要,很好保证程序的健壮性)。书中举例的JAVA IO 的类图,明明白白是使用装饰者模式进行IO操作增强。

ps:题外话,在消化这个模式的时候,我尝试用大白话告诉我女朋友。嗯,还挺好懂,消化知识的一种方式就是大白话和身边人姜明明白。可以继续尝试。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值