装饰器模式--介绍、应用及代码

定义:Decorator装饰器,顾名思义,就是动态地给一个对象添加一些额外的职责,就好比为房子进行装修一样。因此,装饰器模式具有如下的特征:

它必须具有一个装饰的对象。

它必须拥有与被装饰对象相同的接口。

它可以给被装饰对象添加额外的功能。

用一句话总结就是:保持接口,增强性能。

装饰器通过包装一个装饰对象来扩展其功能,而又不改变其接口,这实际上是基于对象的适配器模式的一种变种。它与对象的适配器模式的异同点如下。

相同点:都拥有一个目标对象。

不同点:适配器模式需要实现另外一个接口,而装饰器模式必须实现该对象的接口。

重点理解:

1、知道哪个是被装饰的对象,哪个是装饰器;

2、重中之重:一定要明确传给装饰器的对象,比如下面代码中,如果你是一步一步装饰,切记你一定要把前一步装饰后的对象传给下一步进行装饰的装饰器;否则就达不到所有装饰的效果。朋友们可以下去自己试试,如果把传下面这些装饰器类中的对象改成source,是不会保存上一次装饰效果的。切记!!!

// 不满意?行,咱们继续进行装饰,还是得花钱,给装修房子再增加3K
		SourceI source1w5 = new Decorator1W5(source1w2);
		// 房子第二次装饰好了,再看看1W5的房子满意不
		System.out.println("----第二次装饰完毕,房子信息如下:----");
		source1w5.build();
		// 还不满意?你真挑,不过没关系,咱们有钱,再加点,给装修房子再增加3K
		SourceI source1w8 = new Decorator1W8(source1w5);
		// 房子第一次装饰好了,再看看1W2的房子满意不
		System.out.println("----第三次装饰完毕,房子信息如下:----");
		source1w8.build();

实例:亲自监督经历过装修房子事宜,特用该经历举例。

------------接口实现:

//装修房子操作封装
public interface SourceI {
	public void build();
}

//装饰对象原始类--房子被装修公司按1W元协议进行半包装修
public class SourceImp implements SourceI {
	@Override
	public void build() {
		// TODO Auto-generated method stub
		System.out.println("弄水电");
		System.out.println("粉刷墙壁");
		System.out.println("铲墙皮");	
	}

}

//装饰器类--1W2装修公司增加服务
public class Decorator1W2 implements SourceI {
	private SourceI source=new SourceImp();
	
	public Decorator1W2(SourceI source){
		this.source=source;
	}
	@Override
	public void build() {
		// TODO Auto-generated method stub
		source.build();
		this.buildExtra();
	}
	
	public void buildExtra(){
		System.out.println("1W2服务增加,房子增加灯饰");
	}
}

//装饰器类--1W5装修公司增加服务
public class Decorator1W5 implements SourceI {
	private SourceI source=new SourceImp();
	
	public Decorator1W5(SourceI source){
		this.source=source;
	}
	@Override
	public void build() {
		// TODO Auto-generated method stub
		source.build();
		this.buildExtra();
	}
	
	public void buildExtra(){
		System.out.println("1W5服务增加,房子增加壁纸");
	}
}

//装饰器类--1W8装修公司增加服务
public class Decorator1W8 implements SourceI {
	private SourceI source=new SourceImp();
	
	public Decorator1W8(SourceI source){
		this.source=source;
	}
	@Override
	public void build() {
		// TODO Auto-generated method stub
		source.build();
		this.buildExtra();
	}
	
	public void buildExtra(){
		System.out.println("1W8服务增加,房子增加木地板");
	}
}

public class DecoratorTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// 首先,肯定是得把毛坯房进行基本装修,也就是装修对象肯定是唯一的
		SourceI source = new SourceImp();
		// 房子装修好了,基本装修,一分价钱一分货,让我们看看1W的房子满意不
		System.out.println("----房子基础装修完毕,房子信息如下:----");
		source.build();
		// 不满意?行,咱们进行装饰,不过当然得花钱,给装修房子增加2K
		SourceI source1w2 = new Decorator1W2(source);
		// 房子第一次装饰好了,再看看1W2的房子满意不
		System.out.println("----第一次装饰完毕,房子信息如下:----");
		source1w2.build();
		// 不满意?行,咱们继续进行装饰,还是得花钱,给装修房子再增加3K
		SourceI source1w5 = new Decorator1W5(source1w2);
		// 房子第二次装饰好了,再看看1W5的房子满意不
		System.out.println("----第二次装饰完毕,房子信息如下:----");
		source1w5.build();
		// 还不满意?你真挑,不过没关系,咱们有钱,再加点,给装修房子再增加3K
		SourceI source1w8 = new Decorator1W8(source1w5);
		// 房子第一次装饰好了,再看看1W2的房子满意不
		System.out.println("----第三次装饰完毕,房子信息如下:----");
		source1w8.build();
		//当然啦,如果有钱淫,直接一次性就定制1W8的服务,给你的房子跟分三次装饰后的房子
		//信息是一样的,但是一次性服务的话,装修公司必须一次性到位,这个时候装饰公司是这样子的
		SourceI sourceObj =new Decorator1W8(new Decorator1W5(new Decorator1W2(source)));
		System.out.println("----装修公司服务一次性到位,房子信息如下:----");
		sourceObj.build();
	}

}

---------------抽象类实现:

//装修房子操作封装
public abstract class AbstractSource {
	public abstract void build();
}

//装饰对象原始类--房子被装修公司按1W元协议进行半包装修
public class SourceImp extends AbstractSource {
	
	@Override
	public void build() {
		// TODO Auto-generated method stub
		System.out.println("弄水电");
		System.out.println("粉刷墙壁");
		System.out.println("铲墙皮");
	}

}

//装饰器类--1W2装修公司增加服务
public class Decorator1W2 extends AbstractSource {

	private AbstractSource source=new SourceImp();
	public Decorator1W2(AbstractSource source){
		this.source=source;
	}
	@Override
	public void build() {
		// TODO Auto-generated method stu
		source.build();
		this.buildExtra();
	}
	
	public void buildExtra(){
		System.out.println("1W2服务增加,房子增加灯饰");
	}
}

//装饰器类--1W5装修公司增加服务
public class Decorator1W5 extends AbstractSource {

	private AbstractSource source=new SourceImp();
	public Decorator1W5(AbstractSource source){
		this.source=source;
	}
	@Override
	public void build() {
		// TODO Auto-generated method stu
		source.build();
		this.buildExtra();
	}
	
	public void buildExtra(){
		System.out.println("1W5服务增加,房子增加壁纸");
	}
}

//装饰器类--1W8装修公司增加服务
public class Decorator1W8 extends AbstractSource {

	private AbstractSource source=new SourceImp();
	public Decorator1W8(AbstractSource source){
		this.source=source;
	}
	@Override
	public void build() {
		// TODO Auto-generated method stu
		source.build();
		this.buildExtra();
	}
	
	public void buildExtra(){
		System.out.println("1W8服务增加,房子增加木地板");
	}
}

public class DecoratorTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// 首先,肯定是得把毛坯房进行基本装修,也就是装修对象肯定是唯一的
		AbstractSource source = new SourceImp();
		// 房子装修好了,基本装修,一分价钱一分货,让我们看看1W的房子满意不
		System.out.println("----房子基础装修完毕,房子信息如下:----");
		source.build();
		// 不满意?行,咱们进行装饰,不过当然得花钱,给装修房子增加2K
		AbstractSource source1w2 = new Decorator1W2(source);
		// 房子第一次装饰好了,再看看1W2的房子满意不
		System.out.println("----第一次装饰完毕,房子信息如下:----");
		source1w2.build();
		// 不满意?行,咱们继续进行装饰,还是得花钱,给装修房子再增加3K
		AbstractSource source1w5 = new Decorator1W5(source1w2);
		// 房子第二次装饰好了,再看看1W5的房子满意不
		System.out.println("----第二次装饰完毕,房子信息如下:----");
		source1w5.build();
		// 还不满意?你真挑,不过没关系,咱们有钱,再加点,给装修房子再增加3K
		AbstractSource source1w8 = new Decorator1W8(source1w5);
		// 房子第一次装饰好了,再看看1W2的房子满意不
		System.out.println("----第三次装饰完毕,房子信息如下:----");
		source1w8.build();
		//当然啦,如果有钱淫,直接一次性就定制1W8的服务,给你的房子跟分三次装饰后的房子
		//信息是一样的,但是一次性服务的话,装修公司必须一次性到位,这个时候装饰公司是这样子的
		AbstractSource sourceObj =new Decorator1W8(new Decorator1W5(new Decorator1W2(source)));
		System.out.println("----装修公司服务一次性到位,房子信息如下:----");
		sourceObj.build();
	}

}


运行结果:



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值