欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-05-04 19:24:27
...

    装饰器模式(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. 比继承更灵活也意味着笔比继承更容易出错。由于使用装饰器模式,可以比继承关系需更少的类。使用较少的类,当然使设计容易进行。但是,使用装饰器会比继承产生更多的对象。更多的对象会使得差错变得困难。