设计模式之装饰器模式

内容抄自《设计模式》清华大学出版社,2011

动机:替代继承

定义:动态给一个对象增加一些额外的功能,比生成子类更灵活

结构分析:

包含角色:
1.Component(抽象构件)
2.ConcreteComponent(具体构件)
3.Decorator(抽象装饰类)
4.ConcreteDecorator(具体装饰类)

模式分析: 核心在于抽象装饰类
 

public class Decorator implements Component{
    private Component component;
    @Override
    public void operation(){
        component.operation();
    }
}

优点:

1.装饰模式可以提供比继承更多的灵活性
2.可以通过一种动态的方式来扩展一个对象的功能,通过配置文件在运行时选择不同的装饰器,从而实现不同的行为
3.具体构件类与具体装饰类可以独立变化,客户可以根据需要添加具体构件类和具体装饰类,在使用时进行组合,符合开闭原则

缺点:

1.使用时产生很多小对象,增加系统复杂性
2.比继承更容易出错,排查的难度也加大
    
适用环境:


1.以动态透明的方式给一个类添加动态的功能
2.不用继承或不能用继承(final)

模式应用:InputStream

扩展:

1.简化,如果只有一个具体构件类,而没有抽象构件类,则抽象装饰类可以直接作为具体构件的子类
2.简化,如果只有一个具体装饰类,则可以把抽象装饰类和具体的职责合并
3.透明和半透明,就是指调用抽象构件类new对象的时候使用什么类名

与适配器的区别:
装饰器与适配器都有一个别名叫做 包装模式(Wrapper),它们看似都是起到包装一个类或对象的作用,但是使用它们的目的很不一一样。适配器模式的意义是要将一个接口转变成另一个接口,它的目的是通过改变接口来达到重复使用的目的。
而装饰器模式不是要改变被装饰对象的接口,而是恰恰要保持原有的接口,但是增强原有对象的功能,或者改变原有对象的处理方式而提升性能。所以这两个模式设计的目的是不同的。

模式起源猜想:

/** 装饰器
 * @author Administrator
 *
 */
public class DecoratorModel {

	//继承法,缺乏灵活性代码是死的
	static class Pic{
		public void show(){
			System.out.println("这是一张图片");
		}
	}
	static class PicEx extends Pic{
		@Override
		public void show(){
			super.show();
			System.out.println("加边框");
		}
	}
	static class PicExEx extends PicEx{
		@Override
		public void show(){
			super.show();
			System.out.println("挂在墙上");
		}
	}
	public static void mainOld(String[] args) {
		Pic pic = new PicExEx();
		pic.show();
	}
	//继承法----------------------------------
	//包装法
	static class Phone{
		public void show(){
			System.out.println("这是一个手机");
		}
	}
	static class PhoneWrapper{
		private Phone phone;
		public void show(){
			phone.show();
			System.out.println("加个手机壳");
		}
	}
	static class PhoneWrapperWrapper{
		private PhoneWrapper phoneWrapper;
		public void show(){
			phoneWrapper.show();
			System.out.println("再加个手机壳");
		}
	}
	//这样包装也太麻烦了吧
	//办法1
	static interface Mark{
		public void show();
	}
	static class Adapter implements Mark{
		protected Phone phone;
		public Adapter(Phone phone) {
			super();
			this.phone = phone;
		}
		@Override
		public void show(){
			phone.show();
		}
	}
	static abstract class AdapterWrap implements Mark{
		protected Mark mark;
		public AdapterWrap(Mark mark) {
			this.mark = mark;
		}
		@Override
		public abstract void show();
	}
	static class AdapterWrap1 extends AdapterWrap{
		public AdapterWrap1(Mark mark) {
			super(mark);
		}
		@Override
		public void show() {
			this.mark.show();
			System.out.println("加个鸡蛋");
		}
	}
	static class AdapterWrap2 extends AdapterWrap{
		public AdapterWrap2(Mark mark) {
			super(mark);
		}
		@Override
		public void show() {
			this.mark.show();
			System.out.println("再加个鸡蛋");
		}
	}
	public static void main(String[] args) {
		Phone phone = new Phone();
		Adapter adapter = new Adapter(phone);
		AdapterWrap adapterWrap1 = new AdapterWrap1(adapter);
		AdapterWrap adapterWrap2 = new AdapterWrap2(adapterWrap1);
		adapterWrap2.show();
	}
	//在phone能继承的情况下
	static abstract class AbsD extends Phone{
		protected AbsD absd;
		public AbsD(AbsD absd) {
			super();
			this.absd = absd;
		}
		@Override
		public abstract void show();
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值