发布于 2016-01-04 01:15:50 | 191 次阅读 | 评论: 0 | 来源: PHPERZ

这里有新鲜出炉的Java函数式编程,程序狗速度看过来!

Java程序设计语言

java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由Sun Microsystems公司于1995年5月推出的Java程序设计语言和Java平台(即JavaEE(j2ee), JavaME(j2me), JavaSE(j2se))的总称。


代理模式 
代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发 给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而 是通过调用委托类的对象的相关方法,来提供特定的服务。 
按照代理的创建时期,代理类可以分为两种。

静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。 
动态代理:在程序运行时,运用反射机制动态创建而成。

代理模式可以举一个很简单的例子,就是房屋中介,当然我没去过,为了写这个模式,我就去看了一下,买不起房的人你懂得

这里有两个对象,一个是代理对象,一个是被代理对象,代理对象就是房屋中介

今天A君要买房,他看中了一个房子,但是需要很多手续,他本人上市公司老总,没有那么多时间跑,你知道中国就是喜欢难为你,就是喜欢办证,让你跑,A君老总来的,没时间,也不乐意跑,他找到B中介公司,和他们说我看中了那个房子,需要你们代理一下,帮我把三证拿到,我给你佣金,这就是典型的代理,中介不买房,只帮顾客做一下跑腿的事情,真正发出这个买房的动作的是被代理者

现在让我们开始最简单的静态代理模式

代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口这句话很明显,就是告诉我们,代理和被代理的关系

代理对象和被代理对象都需要实现的接口Count

package org.heinrich.proxy;

/**
 * 定义了一个账户
 * 
 * @author heinrich
 * 
 */
public interface Count {

    // 查询账户
    public void queryCount();

    // 修改账户
    public void updateCount();
}

然后就是被代理对象CountImpl

package org.heinrich.proxy;

public class CountImpl implements Count {

    @Override
    public void queryCount() {
        System.out.println("我正在查询账户");

    }

    @Override
    public void updateCount() {
        System.out.println("我正在修改账户");

    }

}

那么现在我们重点来了,就是这个代理对象

package org.heinrich.proxy;
/**
 * 账户的代理类,代理账户的查询还有修改方法
 * @author heinrich
 *
 */
public class CountProxy implements Count{
    
    private CountImpl countImpl;
    
    public CountProxy(CountImpl countImpl) {
        this.countImpl = countImpl;
    }

    public void queryCount(){
        System.out.println("查询前-----");
        countImpl.queryCount();
        System.out.println("查询后-----");
        
    }

    public void updateCount() {
        System.out.println("修改前----");
        countImpl.updateCount();
        System.out.println("修改后----");
        
    }

    public CountImpl getCountImpl() {
        return countImpl;
    }

    public void setCountImpl(CountImpl countImpl) {
        this.countImpl = countImpl;
    }

}

现在见证奇迹的时候到了

package org.heinrich.proxy;

public class CountTest {
    
    public static void main(String[] args) {
        //被代理都像
        CountImpl countImpl = new CountImpl();
        //代理对象
        CountProxy countProxy = new CountProxy(countImpl);
        //代理方法
        countProxy.queryCount();
        countProxy.updateCount();
    }

}


查询前-----
我正在查询账户
查询后-----
修改前----
我正在修改账户
修改后----

静态代理通过观察我们发现,他每次只能代理一个对象,如果在架构的时候你用这个方式,你发现你的代码会出现很多代理对象

能不能有一个代理对象又能买房又能给你租房,还能给你叫车

当然有那就是动态代理

动态代理的特点

首先让我们来了解一下如何使用 Java 动态代理。具体有如下四步骤:

  1. 通过实现 InvocationHandler 接口创建自己的调用处理器;

  2. 通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类;

  3. 通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型;

  4. 通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入。

public interface InvocationHandler { 
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable; 

参数说明: 
Object proxy:指被代理的对象。 
Method method:要调用的方法 
Object[] args:方法调用时所需要的参数 

可以将InvocationHandler接口的子类想象成一个代理的最终操作类,替换掉ProxySubject。 

Proxy类: 
Proxy类是专门完成代理的操作类,可以通过此类为一个或多个接口动态地生成实现类,此类提供了如下的操作方法: 
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, 
InvocationHandler h) 
                               throws IllegalArgumentException 
参数说明: 
ClassLoader loader:类加载器 
Class<?>[] interfaces:得到全部的接口 
InvocationHandler h:得到InvocationHandler接口的子类实例

上代码

新建一个什么都可以做的万能代理对象

CountInvocationHandler

package org.heinrich.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 *实现一个动态的代理对象 
 */
public class CountInvocationHandler implements InvocationHandler {

    
    //目标对象,也就是买房的人,就是买房的那个人的实现
    private Object target;
    //通过构造器把买房的传入
    public CountInvocationHandler(Object target) {
        super();
        this.target = target;
    }

    /**
     * 目标对象调用的方法,也就是房屋中介需要代理的东西
     */
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        System.out.println("======before======");
           Object result = method.invoke(target, args);
        System.out.println("======after======");
        return result;
    }
    
    
    /**
     *获取目标对象的代理方法 ,返回一个代理对象,也就是返回买房的人的接口
     */
    public Object getProxy(){
        
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }
    
}


/**
*用于测试的方法
*/
package org.heinrich.proxy;

public class DynamicProxyTest {
    
    
    public static void main(String[] args) {
        
        
        CountImpl count = new CountImpl();创建一个买房的对象
        CountInvocationHandler handler = new CountInvocationHandler(count);//找到房屋中介
    
        Count proxy = (Count)handler.getProxy();房屋中介帮你代理
        proxy.updateCount();//你只要做你自己买房的动作
    }

}


======before======
我正在修改账户
======after======


其实我自己现在也是不是很明白准备去看源码,到时候分享给大家,
这个模式主要是搞清楚代理对象和被代理的对象,也就是委托作


最新网友评论  共有(0)条评论 发布评论 返回顶部

Copyright © 2007-2017 PHPERZ.COM All Rights Reserved   冀ICP备14009818号  版权声明  广告服务