• Java 设计模式-装饰器模式(Decorator)


        装饰器模式(Decorator Pattern)又名包装模式(Wrapper Pattern)。装饰模式以对客户透明的方式扩展对象的功能,是继承关系的一种替代。换言之,客户端不会觉得对象在装饰前和装饰后有什么不同。

         装饰器模式(Decorator Pattern)中的各个角色:

    • 抽象构件(Componet)角色:给出一个抽象接口,规范准备接收附加责任的对象。
    • 具体构件(Concrete Componet)角色:定义一个将要接收附加责任的类
    • 装饰(Decorator)角色:持有一个构件(Componet)对象的实例,并定义一个与构件接口一致的接口
    • 具体装饰(Concrete Decorator)角色:负责给构件对象贴上附加的责任

    什么情况下需要使用装饰器模式:

    1. 需要扩展一个类的功能,或给一个类增加附加的责任
    2. 需要动态地给一个对象增加更能,这些功能可以动态地删除
    3. 需要增加一些基本功能的排列组合而产生非常大的功能,从而是关系继承变的不现实。
    /**
     * 抽象构件
     * @author zhangwei_david
     * @version $Id: Animal.java, v 0.1 2014年10月20日 下午10:13:25 zhangwei_david Exp $
     */
    public interface Animal {
        public void doStuff();
    }
    
    /**
     *具体构件
     * @author zhangwei_david
     * @version $Id: Rat.java, v 0.1 2014年10月20日 下午10:14:21 zhangwei_david Exp $
     */
    public class Rat implements Animal {
    
        /**
         * @see com.cathy.demo.pattern.composite.reflect.Animal#doStuff()
         */
        public void doStuff() {
            System.out.println("Jerry will play with Tom.");
        }
    
    }
    
    /**
     *抽象装饰器角色
     * @author zhangwei_david
     * @version $Id: Feature.java, v 0.1 2014年10月20日 下午10:14:59 zhangwei_david Exp $
     */
    public interface Feature {
    
        public void load();
    }
    
    /**
     *具体装饰器角色
     * @author zhangwei_david
     * @version $Id: FlyFeature.java, v 0.1 2014年10月20日 下午10:16:20 zhangwei_david Exp $
     */
    public class FlyFeature implements Feature {
    
        /**
         * @see com.cathy.demo.pattern.composite.reflect.Feature#load()
         */
        public void load() {
            System.out.println("增加翅膀。。。。");
        }
    
    }
    
    /**
     *具体装饰器角色
     * @author zhangwei_david
     * @version $Id: DigFeature.java, v 0.1 2014年10月20日 下午10:17:13 zhangwei_david Exp $
     */
    public class DigFeature implements Feature {
    
        /**
         * @see com.cathy.demo.pattern.composite.reflect.Feature#load()
         */
        public void load() {
            System.out.println("增加钻地能力。。。");
        }
    
    }
    /**
     *装饰器反射实现类
     * @author zhangwei_david
     * @version $Id: DecorateAnimal.java, v 0.1 2014年10月20日 下午10:18:06 zhangwei_david Exp $
     */
    public class DecorateAnimal implements Animal {
        private Animal                   animal;
    
        private Class<? extends Feature> clz;
    
        /**
         * @see com.cathy.demo.pattern.composite.reflect.Animal#doStuff()
         */
        public void doStuff() {
            InvocationHandler handler = new InvocationHandler() {
    
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    Object obj = null;
                    if (Modifier.isPublic(method.getModifiers())) {
                        obj = method.invoke(clz.newInstance(), args);
                    }
                    animal.doStuff();
                    return obj;
                }
            };
            ClassLoader cl = getClass().getClassLoader();
            Feature proxy = (Feature) Proxy.newProxyInstance(cl, clz.getInterfaces(), handler);
            proxy.load();
    
        }
    
        public DecorateAnimal(Animal animal, Class<? extends Feature> clz) {
            super();
            this.animal = animal;
            this.clz = clz;
        }
    
    }
    /**
     *
     * @author zhangwei_david
     * @version $Id: TestClient.java, v 0.1 2014年10月20日 下午10:23:34 zhangwei_david Exp $
     */
    public class TestClient {
    
        public static void main(String[] args) {
            Animal jerry = new Rat();
            jerry = new DecorateAnimal(jerry, FlyFeature.class);
            jerry = new DecorateAnimal(jerry, DigFeature.class);
            jerry.doStuff();
        }
    }
    

     结果是:

    增加钻地能力。。。
    增加翅膀。。。。
    Jerry will play with Tom.
    

    装饰器(Decorator)模式的优缺点:

    1. 装饰器模式(decorator Pattern)与继承关系的目的都是扩展对象的功能,但是装饰器模式可以提供比继承更多的灵活性。装饰器(Decorator)允许系统动态地决定贴上一个需要的装饰,或者除掉一个不必要的装饰。而继承关系则不同,继承关系是静态的,他在系统运行前就已经决定了。
    2. 通过使用不同的装饰器以及这些装饰器的排列组合,设计师可以创造出很多不同的行为的组合。
    3. 比继承更灵活也意味着笔比继承更容易出错。由于使用装饰器模式,可以比继承关系需更少的类。使用较少的类,当然使设计容易进行。但是,使用装饰器会比继承产生更多的对象。更多的对象会使得差错变得困难。
  • 相关阅读:
    高放的c++学习笔记之函数基础
    高放的c++学习笔记之关联容器
    高放的c++学习笔记之lambda表达式
    二分图小结
    送给大一学弟学妹的几句话
    网络流小结
    后缀数组小结
    hdu5353
    UVALive 5792 Diccionário Portuñol
    概率dp小结
  • 原文地址:https://www.cnblogs.com/wei-zw/p/8797824.html
Copyright © 2020-2023  润新知