装饰模式的定义:

  动态地将责任附加到对象向,若要扩展功能,装饰模式提供了比继承更有弹性的替代方案。

  遵循的设计原则是开闭原则,也是对扩展开放,对修改关闭。

下面是类图

示例代码

/**
 *定义被装饰者 
 *
 */
public interface Human {

    public void  wearClothers();
    
    public void  walkToWhere();
}


/**
 * 定义抽象装饰者
 * 
 */
public abstract class Decorate implements Human {

    Human human;

    public Decorate(Human human) {
        this.human = human;
    }

    public void wearClothers() {
        this.human.wearClothers();
    }

    public void walkToWhere() {
        this.human.walkToWhere();
    }
}


/**
 * 
 *装饰者 zero
 */
public class DecorateZero extends Decorate{

    public DecorateZero(Human human) {
        super(human);
    }
    
    @Override
    public void walkToWhere() {
        super.walkToWhere();
        System.out.println("Zero.............walkToWhere");
    }
    
    @Override
    public void wearClothers() {
        super.wearClothers();
        System.out.println("Zero.............wearClothers");
    }
}


/**
 * 装饰者two
 *
 */
public class DecorateTwo extends Decorate{

    public DecorateTwo(Human human) {
        super(human);
    }
    @Override
    public void walkToWhere() {
        super.walkToWhere();
        System.out.println("Two.............walkToWhere");
    }
    
    @Override
    public void wearClothers() {
        super.wearClothers();
        System.out.println("Two.............wearClothers");
    }
}

//
public class DecorateFirst extends Decorate{

    public DecorateFirst(Human human) {
        super(human);
    }
    
    @Override
    public void walkToWhere() {
        super.walkToWhere();
        System.out.println("First.............walkToWhere");
    }
    
    @Override
    public void wearClothers() {
        super.wearClothers();
        System.out.println("First.............wearClothers");
    }
}


/**
 * 
 *测试代码
 */
public class Test {

    public static void main(String[] args) {
        DecorateZero zero=new DecorateZero(new DecorateFirst(new DecorateTwo(new Human() {
            //这里装饰者原有的行为,这里我没有具体去写实现类。
            @Override
            public void wearClothers() {
                // TODO Auto-generated method stub
                System.out.println("1111111wearClothers1111111");
                
            }
            
            @Override
            public void walkToWhere() {
                // TODO Auto-generated method stub
                System.out.println("1111111walkToWhere1111111");
            }
        })));
        zero.walkToWhere();
        System.out.println("*******************************************");
        zero.wearClothers();
    }
}

//测试结果
    1111111walkToWhere1111111
    Two.............walkToWhere
    First.............walkToWhere
    Zero.............walkToWhere
    *******************************************
    1111111wearClothers1111111
    Two.............wearClothers
    First.............wearClothers
    Zero.............wearClothers

 关键点:
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、装饰者模式的设计原则为:对扩展开放、对修改关闭,这句话体现在我如果想扩展被装饰者类的行为,无须修改装饰者抽象类,只需继承装饰者抽象类,实现额外的一些装饰或者叫行为即可对被装饰者进行包装。

装饰Java.io类

java.io包内的类太多了,简只是……”排山倒海“,其实是因为里面许多类都是装饰者,其实java.io也引出装饰者模式的一个缺点:利用装饰着模式,常常设计中有大量的小类,数量实在太多,造成使用者非常大的困扰。了解装饰者模式的原理看起就会简单多了。

编写自己的java.io装饰者

功能:把输入的大写字母写成小写
例如:This is LONGHAIBO,使用此装饰者变成this is longhaibo

public class TestDecorate {

    public static void main(String[] args) {
        
        int c;
        try (InputStream in = new LowerCaseIputStream(new BufferedInputStream(
                new FileInputStream("src/decorate.txt")))) {
            while ((c=in.read())>0) {
                System.out.print((char)c);
            }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        
    }
}

/**
 * Java io 装饰者模式
 * 功能:把输入的大写字母写成小写
 * 例如:This is LONGHAIBO,使用此装饰者变成this is longhaibo
 * 
 */
class LowerCaseIputStream extends FilterInputStream {

    protected LowerCaseIputStream(InputStream in) {
        super(in);
    }
    //针对字节
    @Override
    public int read() throws IOException {
        int c=super.read();
        return (c==-1?c:Character.toLowerCase((char)c));
    }
    //针对字节数组
    @Override
    public int read(byte[] b, int off, int len) throws IOException {
        int result=super.read(b, off, len);
        for (int i = off; i < off+result; i++) {
            b[i]=(byte)Character.toLowerCase((char)b[i]);
        }
        return result;
    }

}

输出结果

this is longhaibo

参考资料

head_first设计模式(中文版)

http://blog.csdn.net/jason0539/article/details/22713711

 

  

posted on 2015-05-19 15:46  一天做一件小事  阅读(592)  评论(0编辑  收藏  举报