关闭

装饰模式

386人阅读 评论(0) 收藏 举报

文章摘抄至 http://www.cnblogs.com/java-my-life/archive/2012/04/20/2455726.html

 

  装饰模式又名包装(Wrapper)模式。装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。


装饰模式的结构

  装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任。换言之,客户端并不会觉得对象在装饰前和装饰后有什么不同。装饰模式可以在不使用创造更多子类的情况下,将对象的功能加以扩展。

  装饰模式的类图如下:

 

  在装饰模式中的角色有:

     ●  抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。

  ●  具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类。

  ●  装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。

  ●  具体装饰(ConcreteDecorator)角色:负责给构件对象“贴上”附加的责任。

 

抽象构件角色

public interface Component {
    public void sampleOperation();
}

 

具体构件角色

public class ConcreteComponent implements Component {

    @Override
    public void sampleOperation() {
        // 写相关的业务代码
    }

}

 

装饰角色

public class Decorator implements Component{
    private Component component;
    public Decorator(Component component){
        this.component = component;
    }

    @Override
    public void sampleOperation() {
        // 委派给构件
        component.sampleOperation();
    }
    
}

 

具体装饰角色

public class ConcreteDecoratorA extends Decorator {

    public ConcreteDecoratorA(Component component) {
        super(component);
    }
    
    @Override
    public void sampleOperation() {
     super.sampleOperation();
        // 写相关的业务代码
    }
}

 

public class ConcreteDecoratorB extends Decorator {

    public ConcreteDecoratorB(Component component) {
        super(component);
    }
    
    @Override
    public void sampleOperation() {
      super.sampleOperation();
        // 写相关的业务代码
    }
}

 

   在此 以一家人作画为例 写了5个java类来描述说明Decorator设计模式的实现方式;

   这个例子举的不太好,但足以说明问题。下面是具体的代码。

 

  1、 Work.java     接口

  2、 Son.java      被装饰者-负责画画

  3、 Mother.java   装饰者-负责上颜色

  4、 Father.java   装饰者-负责装画框

  5、 DecoratorTest.java 带有main方法的测试类,

        模拟3种调用情况:A,只画画;

                         B,画画,上色;

                         C, 画画,上色,装框

 

 抽象构建

package hb.decorator;

public interface Work {
	public void paint();
}

 具体构建

package hb.decorator;

public class Son implements Work {
	public void paint() {
		System.out.println("儿子用铅笔画好了一幅画。");
	}
}

 装饰角色(如果子类不是很多,这个可以不要,直接使用下面Mother、Father类,将Work的具体实现作为该类的属性即可)

package hb.decorator;

public class MyDecorator implements Work {

	Work work;
	
	public MyDecorator(Work work){
		this.work = work;
	}
	
	@Override
	public void paint() {
		work.paint();
	}

}

 具体装饰实现——将具体构建作为装饰的组成部分

package hb.decorator;

public class DecoratorMother extends MyDecorator{

	public DecoratorMother(Work work) {
		super(work);
	}

	@Override
	public void paint() {
		// 妈妈装饰者做的职责
		System.out.println("妈妈正在做给画上颜色前的准备工作。");

		// 被装饰者做的职责
		super.paint();

		// 妈妈装饰者做的职责
		System.out.println("妈妈给画上好了颜色。");
	}

}

  具体装饰实现——将具体装饰构建作为装饰的组成部分----层层包裹

package hb.decorator;

public class DecoratorFather extends MyDecorator{

	public DecoratorFather(Work work) {
		super(work);
	}
	
	@Override
	public void paint() {
		// 爸爸装饰者做的职责
		System.out.println("爸爸正在做上画框前的准备工作。");

		// 被装饰者做的职责
		super.paint();

		// 爸爸装饰者做的职责
		System.out.println("爸爸给画装好了一个画框。");
		
	}

}

 

package hb.decorator;

public class DecoratorTestDemo {
	public static void main(String[] args) {

		// 只画铅笔画
		Work work = new Son();
		work.paint();
		System.out.println("\n");

		// 除了画铅笔画,还要给画上颜色
		work = new DecoratorMother(work);
		work.paint();
		System.out.println("\n");

		// 除了画铅笔画,给画上颜色,还要给画上画框
		work = new DecoratorFather(work);
		work.paint();

	}
}

 

打印结果:

儿子用铅笔画好了一幅画。

 

 

妈妈正在做给画上颜色前的准备工作。

儿子用铅笔画好了一幅画。

妈妈给画上好了颜色。

 

 

爸爸正在做上画框前的准备工作。

妈妈正在做给画上颜色前的准备工作。

儿子用铅笔画好了一幅画。

妈妈给画上好了颜色。

爸爸给画装好了一个画框。

 

装饰模式的简化

  大多数情况下,装饰模式的实现都要比上面给出的示意性例子要简单。

  如果只有一个ConcreteComponent类,那么可以考虑去掉抽象的Component类(接口),把Decorator作为一个ConcreteComponent子类。如下图所示:

 

  如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合并成一个类。甚至在只有两个ConcreteDecorator类的情况下,都可以这样做。如下图所示:


 

装饰模式的优点

  (1)装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性。装饰模式允许系统动态决定“贴上”一个需要的“装饰”,或者除掉一个不需要的“装饰”。继承关系则不同,继承关系是静态的,它在系统运行前就决定了。

  (2)通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。

装饰模式的缺点

  由于使用装饰模式,可以比使用继承关系需要较少数目的类。使用较少的类,当然使设计比较易于进行。但是,在另一方面,使用装饰模式会产生比使用继承关系更多的对象。更多的对象会使得查错变得困难,特别是这些对象看上去都很相像。

 

  • 大小: 31.4 KB
  • 大小: 29.5 KB
  • 大小: 19.6 KB
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:329040次
    • 积分:8937
    • 等级:
    • 排名:第2254名
    • 原创:1096篇
    • 转载:14篇
    • 译文:0篇
    • 评论:5条
    最新评论