装饰模式简介

本文通过僵尸游戏示例,详细解析了装饰模式的概念与应用。装饰模式允许在不改变原有类的基础上,通过包裹对象来扩展功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以下内容均为博主查阅资料后理解整理而得,如若转载,请注明出处: http://blog.youkuaiyun.com/cin_ie/article/details/6911507


装饰模式,又名包裹模式,顾名思义该模式采取层层包裹的方式来实现最终的功能,最终的什么功能呢?当然是增强原有类的功能。


装饰模式要求该结构中所有的参与者都实现相同的接口或者继承自相同的父类,其组成一般包括

(1)被装饰的类:执行基本的业务逻辑,比如下面例子代码中的“普通僵尸”,僵尸都会移动,这是僵尸们的基本逻辑

(2)被装饰类的父类或者接口:规范装饰类与被装饰类在结构上一致

(3)抽象装饰类(并非java语法上的抽象类):个人理解,该组件用于连接具体装饰类与被装饰类。

(4)具体装饰类:具体需要增加的功能,如:冷冻僵尸会冻住植物这个功能(详见例子代码)。

先给出具体代码

抽象被装饰角色

/**
 * 这是装饰结构的规范接口,所有的僵尸都会移动
 * Oct 27, 2011
 * @author 车前猛跑
 */
public interface IZombie {

	public void move();
	
}

将要被装饰的类

/**
 * 普通业务逻辑所在的被装饰类,可以通过被装饰类装饰,来增强其功能
 * Oct 27, 2011
 * @author 车前猛跑
 */
public class PopZombie implements IZombie{

	@Override
	public void move() {
		System.out.println("僵尸会移动");
	}

	
}

抽象装饰类

/**
 * 抽象装饰类,我觉得叫:“装饰类接口”更合适
 * Oct 27, 2011
 * @author 车前猛跑
 */
public class ZombieDecorator implements IZombie{

	private IZombie iZombie;
	
	public ZombieDecorator () {
		
	}
	
	public ZombieDecorator (IZombie iZombie) {
		this.iZombie = iZombie;
	}

	@Override
	public void move() {
		iZombie.move();
	}

}

具体装饰类:冰冻僵尸

/**
 * 具体装饰类,该类增强了冷冻僵尸的冰冻功能
 * Oct 27, 2011
 * @author 车前猛跑
 */
public class ColdZombie extends ZombieDecorator{


	public ColdZombie () {
		
	}
	
	public ColdZombie (IZombie iZombie) {
		super(iZombie);
	}


	@Override
	public void move() {
		super.move();
		this.cold();
	}


	public void cold () {
		System.out.println("冰冻僵尸会冰住植物");
	}
}
具体装饰类:帽子僵尸

/**
 * 具体装饰类,该类增强了帽子僵尸的增强防御功能
 * Oct 27, 2011
 * @author 车前猛跑
 */
public class HatZombie extends ZombieDecorator{

	public HatZombie () {
		
	}
	
	public HatZombie (IZombie iZombie) {
		super (iZombie);
	}
	
	public void move () {
		super.move();
		this.defance();
	}
	
	public void defance () {
		System.out.println("带帽子的僵尸防御力很强哦");
	}
}
客户端调用:看完下面的代码,熟悉模版方法模式的同行可能会想,这不就跟模版方法模式差不多吗?把基本功能写到模版方法里,剩下的写到子类中。

/**
 * 
 * Oct 27, 2011
 * @author 车前猛跑
 */
public class Ex {

	public static void main (String [] args) {
		// 普通僵尸
		IZombie popZombie = new PopZombie();
		// 冷冻僵尸
		IZombie coldZombie = new ColdZombie (popZombie);
		// 戴帽子的僵尸
		IZombie hatZombie = new HatZombie (popZombie);
		popZombie.move();
		System.out.println("-----------");
		coldZombie.move();
		System.out.println("-----------");
		hatZombie.move();
		// 到这里,熟悉模版方法模式的同行可能会想,
		//这不就跟模版方法模式差不多吗?把基本功能写到模版方法里,剩下的写到子类中,如果这样想,请接着看下面的客户端调用
	}
}
另一个客户端调用

/**
 * 
 * Oct 27, 2011
 * @author 车前猛跑
 */
public class Ex {

	public static void main (String [] args) {
		// 普通僵尸
		IZombie popZombie = new PopZombie();
		// 冷冻僵尸
		IZombie coldZombie = new ColdZombie (popZombie);
		// 戴帽子的僵尸
		IZombie hatZombie = new HatZombie (popZombie);
		// 戴帽子的冷冻僵尸,注意这里的参数是"戴帽子的僵尸的实例",而不是"普通僵尸的实例"
		IZombie coldhatZombie = new HatZombie (coldZombie);
		popZombie.move();
		System.out.println("-----------");
		coldZombie.move();
		System.out.println("-----------");
		hatZombie.move();
		System.out.println("-----------");
		coldhatZombie.move();
		
	}
}
在这个客户端调用里,最后我们创建了一个戴着帽子的冰冻僵尸,这样就能看出装饰模式的真正用意了吧,模版方法模式是无法实现这样的功能的。

以上僵尸的例子就解释了装饰(包裹)模式的用意与特性。通过包裹老的类型的对象,得到新的功能更强的类型。








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值