装饰者模式学习

感谢liuguly的文章   原文地址:http://www.blogjava.net/liuguly/archive/2010/08/31/330390.html

该模式挺难理解,想了快一晚上。。。才算有点眉目。。。然后照搬一些java.io类还有servlet里面的过滤器终于有所领悟。
使用接口实现,下面给出代码:

  1/**
  2 *定义被装饰者
  3 **/

  4public interface Human {
  5    public void wearClothes();
  6    public void walkToWhere();
  7}

  8/**
  9 *定义装饰者是个抽象类
 10 **/

 11public abstract class Decorator implements Human {
 12    private Human human;
 13    
 14    public Decorator(Human human){
 15        this.human=human;
 16    }

 17    public void walkToWhere() {
 18         human.walkToWhere();
 19    }

 20    public void wearClothes() {
 21         human.wearClothes();
 22    }

 23}

 24/**
 25 *定义三种装饰,这是第一种
 26 **/

 27public class Decorator_zero extends Decorator {
 28
 29    public Decorator_zero(Human human) {
 30        super(human);
 31    }

 32    private void put(){
 33        System.out.println("进房子");
 34    }

 35    private void finMap(){
 36        System.out.println("书柜找找Map");
 37    }

 38    @Override
 39    public void wearClothes() {
 40        super.wearClothes();
 41        put();
 42    }

 43    @Override
 44    public void walkToWhere() {
 45        super.walkToWhere();
 46        finMap();
 47    }

 48}

 49/**
 50 *这是第二种
 51 **/

 52public class Decorator_first extends Decorator{
 53
 54    public Decorator_first(Human human) {
 55        super(human);
 56    }

 57    private void put(){
 58        System.out.println("去衣柜找找");
 59    }

 60    private void where(){
 61        System.out.println("先找张地图");
 62    }

 63    @Overrde
 64    public void wearClothes() {
 65        super.wearClothes();
 66        put();
 67    }

 68    @Override
 69    public void walkToWhere() {
 70        super.walkToWhere();
 71        where();
 72    }

 73}

 74/**
 75 *这是第三种
 76 **/

 77public class Decorator_second extends Decorator {
 78
 79    public Decorator_second(Human human) {
 80        super(human);
 81    }

 82    private void put(){
 83        System.out.println("找到一件D&G");
 84    }

 85    private void where(){
 86        System.out.println("从地图上找到神秘花园以及城堡");
 87    }

 88    @Override
 89    public void wearClothes() {
 90         super.wearClothes();
 91         put();
 92    }

 93    @Override
 94    public void walkToWhere() {
 95         super.walkToWhere();
 96         where();
 97    }

 98}

 99/**
100 *定义被装饰者,该被装饰者初始状态会有一些自己的装饰
101 **/

102public class Person implements Human {
103
104    public void walkToWhere() {
105        System.out.println("去哪里呢");
106    }

107    public void wearClothes() {
108        System.out.println("穿什么呢");
109    }

110}

111/**
112 *测试类,下面越看越帅。。。怎一个帅字了得。。。这明显
113 *是java.io的层次嘛。。。哈哈
114 **/

115public class Test {
116public static void main(String[] args) {
117    Human human = new Person();
118    Decorator dt = new Decorator_second(new Decorator_first(new Decorator_zero(human)));
119        dt.wearClothes();
120        dt.walkToWhere();  
121    }

122}


关键点:
1、Decorator抽象类中,持有Human接口,方法全部委托给该接口调用,目的是交给该接口的实现类即子类进行调用。
2、Decorator抽象类的子类(具体装饰者),里面都有一个构造方法调用super(human),这一句就体现了抽象类依赖于子类实现即抽象依赖于实现的原则。因为构造里面参数都是Human接口,只要是该Human的实现类都可以传递进去,即表现出Decorator dt = new Decorator_second(new Decorator_first(new Decorator_zero(human)));这种结构的样子。所以当调用dt.wearClothes();dt.walkToWhere()的时候,又因为每个具体装饰者类中,都先调用super.wearClothes和super.walkToWhere()方法,而该super已经由构造传递并指向了具体的某一个装饰者类(这个可以根据需要调换顺序),那么调用的即为装饰类的方法,然后才调用自身的装饰方法,即表现出一种装饰、链式的类似于过滤的行为。
3、具体被装饰者类,可以定义初始的状态或者初始的自己的装饰,后面的装饰行为都在此基础上一步一步进行点缀、装饰。
4、装饰者模式的设计原则为:对扩展开放、对修改关闭,这句话体现在我如果想扩展被装饰者类的行为,无须修改装饰者抽象类,只需继承装饰者抽象类,实现额外的一些装饰或者叫行为即可对被装饰者进行包装。所以:扩展体现在继承、修改体现在子类中,而不是具体的抽象类,这充分体现了依赖倒置原则,这是自己理解的装饰者模式。


你可能感兴趣的:(装饰者模式学习)