第九篇:装饰者模式

今天我们来谈谈装饰者模式! 说起这个模式,相信大家都有过接触,java的IO体系总用过吧,IO体系中各种流都可以见到装饰者的影子,比如BufferedReader和Reader,通过向BufferedReader的构造函数中传入一个Reader,这个Reader就具备了缓冲的能力!

再举个例子,比如你是一个光溜溜的人, 给你套一件麻布衣服,你就成了一个平民,拥有了外出打酱油的能力(不穿衣服你敢出去???) , 再在你麻布衣服上套一层布甲,你成了一个低级士兵,拥有了战斗的能力!  如果再在布甲上面套一层蝙蝠战甲,你就有了蝙蝠侠战斗的能力,有一天,你觉得蝙蝠侠还不够厉害,没关系,脱掉蝙蝠战甲,套上一层钢铁战甲,恭喜你,你成了钢铁侠!


没错,装饰者模式就是这样,一层套一层,每一个对象都可以用来装饰别的对象,也可以被更高级的对象装饰, OK,我们画个图来看看吧!



上面的图很简单明了,因此,我们现在要来思考怎么样来实现这么一个模型呢?要让一个类既能成为装饰者,又能成为被装饰者呢?装饰者和被装饰者看上去是想同的,只不过多了某种能力而已...如果是这样的话,好像如果它们拥有同一个类型的话就可以做到吧!

Ok,我们来写代码吧!

/**一个抽象人类*/
public abstract class AbstractPerson {
	//每个人默认都是光溜溜的
	protected String desc = "光溜溜" ; 
	//此方法没什么作用,只是为了打印测试效果
	public String getDesc(){
		return desc;
	}
	/**每个人都有战斗能力*/
	abstract int combatCount();
}

/**一个光溜溜的男人,默认只有10点战斗力*/
class Man extends AbstractPerson{
	@Override
	int combatCount() {
		return 10;
	}
}


/**一个抽象装饰者类*/
abstract class abstractDecorate extends AbstractPerson{
	//所有装饰者必须持有被装饰者的引用!
	protected AbstractPerson abstractPerson;
	
	public abstractDecorate( AbstractPerson abstractPerson) {
		this.abstractPerson = abstractPerson;
	}
	
	//覆盖描述方法,简单的打印一下!
	@Override
	public String getDesc() {
		return  this.abstractPerson.getDesc()+",套了一层["+this.desc+"],战斗力提示至["+this.combatCount()+"]";
	}
}

接下来创造4个装饰者;

/**一件麻布衣服*/
class Clothes extends abstractDecorate{
	
	public Clothes(AbstractPerson abstractPerson) {
		super(abstractPerson);
		this.desc = "麻布衣服";
	}
	@Override
	int combatCount() {//穿上了麻布衣服,增加30点攻击力
		return this.abstractPerson.combatCount()+30;
	}
}

/**一件布甲*/
class Corselet extends abstractDecorate{
	
	public Corselet(AbstractPerson abstractPerson) {
		super(abstractPerson);
		this.desc = "布甲";
	}
	@Override
	int combatCount() {//穿上了布甲,增加100点攻击力
		return this.abstractPerson.combatCount()+100;
	}
}

/**一件蝙蝠侠战甲*/
class BatCorselet extends abstractDecorate{
	
	public BatCorselet(AbstractPerson abstractPerson) {
		super(abstractPerson);
		this.desc = "蝙蝠侠战甲";
	}
	@Override
	int combatCount() {//穿上了蝙蝠侠战甲,增加1000点攻击力
		return this.abstractPerson.combatCount()+10000;
	}
}

/**一件超级钢铁侠智能战甲*/
class SteelCorselet extends abstractDecorate{
	
	public SteelCorselet(AbstractPerson abstractPerson) {
		super(abstractPerson);
		this.desc = "超级钢铁侠智能战甲";
	}
	@Override
	int combatCount() {//穿上了蝙蝠侠战甲,增加10000000点攻击力
		return this.abstractPerson.combatCount()+10000000;
	}
}


我们来测试一下!

public class Test {
	public static void main(String[] args) {
		AbstractPerson person = new Man();
		person.desc="一个男人";
		person = new Clothes(person);
		person = new Corselet(person);
		person = new BatCorselet(person);
		System.out.println(person.getDesc());
	}
}
输出************************************************

一个男人,套了一层[麻布衣服],战斗力提示至[40],套了一层[布甲],战斗力提示至[140],套了一层[蝙蝠侠战甲],战斗力提示至[10140]

*****************************************************
如果我们想拥有钢铁侠的飞行能力怎么办?很简单嘛!将person = new BatCorselet(person)换成person = new SteelCorselet(person)不就可以了嘛!

在上门代码中,Man是一个最基本的类,它是一个光溜溜的人,没有任何能力,我们通过创造多个装饰者,并挨个将被装饰者包装一遍,使其提高了战斗力,拥有了各种能力,比如套上蝙蝠侠战甲,它就有了开蝙蝠战车的能力(我代码中没写这些) ,而换成钢铁侠战甲,则拥有了飞行能力...

通过上面的代码,我们基本可以得出装饰者模式的定义:那就是能在运行时,动态给某个对象增加新的功能行为,装饰者模式底层就是用组合,装饰者组合被装饰者!



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值