java反射增加装饰模式的普适性

装饰模式(Decorator Pattern)的定义是:在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象来包裹真实的对象。就增加功能来说,装饰模式相比于生成子类更为灵活。使用java的动态代理实现装饰模式会具有更强的灵活性、适应性。下面我们就来写一个使用java动态代理来实现装饰模式效果的例子。

定义一个职责的接口:

/**
 * 能力
 */
interface Feature{
    void ability();
}

职责的两个实现类:

/**
 * 读书的能力
 */
class ReadAbility implements Feature {

    @Override
    public void ability() {
        System.out.println("我会读书、、、");
    }
}

/**
 * 写字的能力
 */
class WriteAbility implements Feature {

    @Override
    public void ability() {
        System.out.println("我会写字。、、、、");
    }
}

定义一个通用的接口,用来扩展实现类的职责:

/**
 * 有什么能力
 */
interface Ability {
    void sayYouAbility();
}

实现通用的接口,来通过反射来模拟装饰模式:

public class ReflectDecorateTest01 implements Ability{
    //用来包装真实对象
    private Ability ability;
    //下面要反射调用的Class对象。
    private Class<? extends Feature> clazz;

    @Override
    public void sayYouAbility() {
        /**
         * 动态代理
         */
        InvocationHandler invocationHandler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object obj = null;
                if(Modifier.isPublic(method.getModifiers())){
                    obj = method.invoke(clazz.newInstance(),args);
                }
                ability.sayYouAbility();//这个地方很重要,不能漏掉, 实现层层调用的功能。
                return obj;
            }
        };
	//生成动态代理对象
        Feature feature = (Feature) Proxy.newProxyInstance(getClass().getClassLoader(),clazz.getInterfaces(),invocationHandler);
        feature.ability();//代理类的调用方法
    }

    public ReflectDecorateTest01(Ability ability, Class<? extends Feature> clazz) {
        this.ability = ability;
        this.clazz = clazz;
    }

    public ReflectDecorateTest01() {
    }

    public static void main(String[] args){
        Ability ability = new Ability() {
            @Override
            public void sayYouAbility() {
                System.out.println("你有什么能力!");
            }
        };
        ability = new ReflectDecorateTest01(ability,ReadAbility.class);//给实现类增加读的能力
        ability = new ReflectDecorateTest01(ability,WriteAbility.class);//给实现类增加写的能力
        ability.sayYouAbility();
    }
}

这样一个通过反射来动态实现装饰模式的功能。下面多说一点装饰模式的东西。装饰模式有什么特点呢?

1、装饰对象和真实对象有相同的接口。这样调用者就能以和真实对象相同的方式和装饰对象交互。

2、装饰对象包含一个真实对象的引用(即上面例子中的Ability接口)。

3、装饰对象接受所有来调用者的请求,并把这些请求转发给真实的对象。

4、装饰对象可以在调用者的方法以前或以后增加一些附加功能。这样就确保了在运行时,不用修改给定对象的结构就可以在外部增加附加的功能。

那么在什么样的地方使用装饰模式呢?

1、需要动态扩展一个类的功能,或给一个类添加附加职责。

2、需要动态的给一个对象添加功能,这些功能可以再动态的撤销。

3、需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实。

4、 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

下面再写一个不通过反射来实现装饰模式的例子:

/**
 * Created by zkn on 2016/11/14.
 * 测试装饰模式
 */
public class DecoratePatternTest01 implements DecorateInterface{

    private DecorateInterface decorateInterface;

    public DecoratePatternTest01(DecorateInterface decorateInterface) {
        this.decorateInterface = decorateInterface;
    }

    @Override
    public void read(){
        decorateInterface.read();
    }

    public static void main(String[] args){
        DecoratePatternTest01 decoratePatternTest01 = new DecoratePatternTest01(new DecorateTest02(new DecorateTest01()));
        decoratePatternTest01.read();
    }
}

/**
 * 装饰模式的接口
 */
interface DecorateInterface {

    void read();
}
/**
 * 装饰接口的第一个实现类
 */
class DecorateTest01 implements DecorateInterface {

    private DecorateInterface decorateInterface;

    @Override
    public void read() {

        System.out.println("我是第一个实现类");
    }

    public DecorateTest01(DecorateInterface decorateInterface) {
        this.decorateInterface = decorateInterface;
    }

    public DecorateTest01() {
    }
}
时间: 2024-09-10 17:00:04

java反射增加装饰模式的普适性的相关文章

JAVA反射獲取屬性名報錯

问题描述 JAVA反射獲取屬性名報錯 反射获取属性名异常,遍历明明存在,指定属性名获取却报错,求指点.代码如下: public class Test2 { private String column1; private List column2; public String getColumn1() { return column1; } public void setColumn1(String column1) { this.column1 = column1; } public List<

Java反射机制的学习

Java反射机制是Java语言被视为准动态语言的关键性质.Java反射机制的核心就是允许在运行时通过Java Reflection APIs来取得已知名字的class类的相关信息,动态地生成此类,并调用其方法或修改其域(甚至是本身声明为private的域或方法). 也许你使用Java已经很长时间了,可是几乎不会用到Java反射机制.你会嗤之以鼻地告诉我,Java反射机制没啥用.或许在J2EE.J2SE等平台,Java反射机制没啥用(具体我也不了解,不多做评论),但是在Android应用开发中,该

浅谈Java反射与代理_java

Java反射机制与动态代理,使得Java更加强大,Spring核心概念IoC.AOP就是通过反射机制与动态代理实现的. 1 Java反射 示例: User user = new User(); user.setTime5Flag("test"); Class<?> cls = Class.forName("com.test.User"); //接口必须public,无论是否在本类内部使用!或者使用cls.getDeclaredMethod(),或者遍历修

java反射机制的实现原理

java反射机制的实现原理反射机制:所谓的反射机制就是java语言在运行时拥有一项自观的能力.通过这种能力可以彻底的了解自身的情况为下一步的动作做准备.下面具体介绍一下java的反射机制.这里你将颠覆原来对java的理解. Java的反射机制的实现要借助于4个类:class,Constructor,Field,Method:其中class代表的时类对象,Constructor-类的构造器对象,Field-类的属性对象,Method-类的方法对象.通过这四个对象我们可以粗略的看到一个类的各个组 成

了解Java 8功能如何让并发性编程变得更容易

在期待已久的 Java 8 版本中,并发性方面已实现了许多改进,其中包括在java.util.concurrent 层级中增加新的类和强大的新并行流 功能.设计流的目的是与lambda 表达式 共同使用,Java 8 的这项增强也使得日常编程的其他很多方面变得更加简便.(参见介绍 Java 8 语言的 指南文章,了解对于 lambda 表达式的介绍及相关 interface改动.) 本文首先介绍了新的 CompletableFuture 类如何更好地协调异步操作.接下来,我将介绍如何使用并行流(

Java反射机制详解_java

本文较为详细的分析了Java反射机制.分享给大家供大家参考,具体如下: 一.预先需要掌握的知识(java虚拟机) java虚拟机的方法区: java虚拟机有一个运行时数据区,这个数据区又被分为方法区,堆区和栈区,我们这里需要了解的主要是方法区.方法区的主要作用是存储被装载的类 的类型信息,当java虚拟机装载某个类型的时候,需要类装载器定位相应的class文件,然后将其读入到java虚拟机中,紧接着虚拟机提取class 中的类型信息,将这些信息存储到方法区中.这些信息主要包括: 1.这个类型的全

Java反射机制的学习总结_java

一.什么是反射机制 简单的来说,反射机制指的是程序在运行时能够获取自身的信息.在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有信息. 二.哪里用到反射机制 有些时候,我们用过一些知识,但是并不知道它的专业术语是什么,在刚刚学jdbc时用过一行代码, Class.forName("com.mysql.jdbc.Driver.class").newInstance();但是那时候只知道那行代码是生成驱动对象实例,并不知道它的具体含义.听了反射机制这节课后,才知道,原来这

聊一聊Java反射_java

这次提到的Java反射涉及的代码比较多.因为工作中经常用到反射,对代码做了很多抽象以及过滤器.虽然代码量很多,但是简单易用,过滤插件也易修改. 下面介绍下工作中哪些地方比较容易用到反射.比如插件或者过滤器,如果抽象的子类比较少,配置成XML等结构也是可以达到同样的效果.如果希望灵活一些,添加了插件或者过滤器代码子类后希望可以直接使用.可能反射会比较好点,通过扫描所有class或者jar文件,得到所有继承的子类.如果每次调用都扫描所有的文件会比较影响性能.所以在实现里面加入反射缓存,对所要获取反射

Java反射机制剖析:简单谈谈动态代理

通过<Java反射机制剖析:定义和API>和<Java反射机制剖析:功能以及举例>的学习,已经对反射有了一定的了解,这一篇通过动态代理的例子来进一步学习反射机制. 1.代理模式 代理模式就是为其他对象提供一种代理来控制对这个对象的访问.其实代理模式是在访问的对象时引入一定程度的间接性,这种间接性可以附加多种用途. 它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系,一个代理类