设计模式之装饰模式(Decorator)

本文通过一个彩铃和广告功能增加的例子,介绍了装饰模式的概念及其在Java中的应用方式。装饰模式允许在不改变现有类的情况下,动态地给对象添加新的职责。

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

          装饰模式就是使用被装饰类的一个子类实例,在客户端将这个子类的实例委托给装饰类,装饰模式是继承关系的一个替代方案。装饰模式在java io、junit中有很好的应用。

 

我们来看一个彩铃的例子:某手机在设计时只有打电话的功能:

Phone.java:

package com.dxy.design.pattern.decorator;

public class Phone {
	
	public void call() {
		//打电话。。。
	}
}


有的用户想在打电话前增加一个彩铃提醒的功能,而有的用户又不想,所以我们可以采用继承的方式来实现:

package com.dxy.design.pattern.decorator;

public class ColorPhone extends Phone {

	@Override
	public void call() {
		//此处播放彩铃...
		super.call();//打电话
	}
	
}


而有的用户希望在打完电话后播放一段广告,我们接着用继承来实现:

package com.dxy.design.pattern.decorator;

public class AdPhone extends Phone {

	@Override
	public void call() {  
		super.call();//打电话      
		//此处播放广告。。。
	}
	
}



这时坑爹的用户们有的想即播放彩铃又播放广告,有的又想增加许多新功能,如果继续用继承会导致子类越来越多,继承关系也越复杂,当使用继承给类增加功能比较麻烦时,我们就应该考虑使用装饰模式了:

定义一个手机接口和实现:

package com.dxy.design.pattern.decorator;

public interface Phone {
	
	public void call() ;
}


 

package com.dxy.design.pattern.decorator;

public class PhoneImpl implements Phone {

	@Override
	public void call() {
		System.out.println("通话中。。。");
	}

}

 

所谓的装饰,也就是把原有的包装一下,使其功能更多,所以这里需要一个装饰类:
手机通话装饰类:

package com.dxy.design.pattern.decorator;

public class PhoneDecorator implements Phone {
	
	private Phone phone;
	
	public PhoneDecorator(Phone phone) {
		this.phone = phone;
	}

	@Override
	public void call() {
		this.phone.call();
	}

}


如果要增加彩铃功能,就增加一个彩铃装饰类:

package com.dxy.design.pattern.decorator;

public class ColorPhoneDecorator extends PhoneDecorator {

	public ColorPhoneDecorator(Phone phone) {
		super(phone);
	}
	
	public void call() {
		System.out.println("播放彩铃");
		super.call();
	}

}

如果要增加广告功能就增加一个广告装饰类:

package com.dxy.design.pattern.decorator;

public class AdPhoneDecorator extends PhoneDecorator {

	public AdPhoneDecorator(Phone phone) {
		super(phone);
	}
	
	public void call() {
		super.call();
		System.out.println("播放广告");
	}

}


如果增加了彩铃功能,我们客户端可以这样调用:

package com.dxy.design.pattern.decorator;

public class Client {
	public static void main(String[] args) {
		Phone phone = new PhoneImpl();
		PhoneDecorator pd = new ColorPhoneDecorator(phone);
		pd.call();
	}
}

如果增加广告,我们就可以这样调用:

package com.dxy.design.pattern.decorator;

public class Client {
	public static void main(String[] args) {
		Phone phone = new PhoneImpl();
		PhoneDecorator pd = new AdPhoneDecorator(phone);
		pd.call();
	}
}

现在你也许还看不出来有什么区别,如果现在要即播放彩铃又播放广告,如果用继承的话还得增加一个新的子类,现在,我们可以这样调用:

package com.dxy.design.pattern.decorator;

public class Client {
	public static void main(String[] args) {
		Phone phone = new PhoneImpl();
		PhoneDecorator pd = new AdPhoneDecorator(new ColorPhoneDecorator(phone));
		pd.call();
	}
}


怎么样,是不是很方便,这比使用继承关系更灵活的扩展了对象的功能,我们可以动态的添加对象的功能,并且对这些功能进行任意的组合进而实现更多的功能,避免了更多的继承关系的实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值