您的位置:首页 > 编程语言 > Java开发

【JAVA】设计模式之代理模式的使用分析

2015-04-07 20:30 639 查看
【JAVA】设计模式之代理模式的使用分析 

分类: Java

1、代理的概念
代理模式即Proxy Pattern,23种java常用设计模式之一。代理模式的主要作用是为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。代理模式的思想是为了提供额外的处理或者不同的操作而在实际对象与调用者之间插入一个代理对象。这些额外的操作通常需要与实际对象进行通信。代理可分为静态代理和动态代理。
2、静态代理代码实现

点击(此处)折叠或打开

/**

 * 用户模块数据库操作接口

 */

public interface IUserDao
{

    

    /**

     * 添加用户

     */

    public void addUser();

    

    /**

     * 删除用户

     */

    public void delUser();

}

点击(此处)折叠或打开

public class UserDaoMySqlImpl
implements IUserDao
{

    @Override

    public void addUser()
{

        System.out.println("UserDaoImpl--Mysql-addUser()");

    }

    @Override

    public void delUser()
{

        System.out.println("UserDaoImpl--Mysql-delUser()");

    }

}

点击(此处)折叠或打开

public class UserDaoProxyImpl
implements IUserDao
{

    public IUserDao userDao;

    

    public UserDaoProxyImpl(IUserDao dao){

        this.userDao
= dao;

    }

    

    @Override

    public void addUser()
{

        userDao.addUser();

    }

    @Override

    public void delUser()
{

        userDao.delUser();

    }

}

 

点击(此处)折叠或打开

/**

 * 测试Main方法

 * @author feng

 *

 */

public class TestMain
{

    /**

     * 测试main方法

     * @param args

     */

    public static
void main(String
[] args){

        IUserDao dao1 =
new UserDaoMySqlImpl();

 
        IUserDao dao2 =
new UserDaoProxyImpl(dao1);

        dao2.addUser();

    }

}

3、动态代理代码实现

点击(此处)折叠或打开

public interface HelloWorld
{

    /**

     * 对外接口

     */

    public void sayHelloWorld();

}

点击(此处)折叠或打开

public class HelloWorldImpl
implements HelloWorld
{

    /**

     * 实现类

     */

    public void sayHelloWorld()
{

        System.out.println("Hello world");

    }

}

点击(此处)折叠或打开

public class HelloWorldProxy
implements InvocationHandler
{

    /**

     * 代理对象

     */

    private Object obj;

    /**

     * 构造方法

     * @param obj

     */

    public HelloWorldProxy(Object obj){

        this.obj
= obj;

    }

    

    /**

     * 默认执行方法

     */

    public Object
invoke(Object
proxy,
Method method,
Object[] args)

            throws
Throwable {

        Object
result = null;

        doBefore();

        result
= method.invoke(obj, args);

        doAfter();

        return
result;

    }

    

    private void doBefore(){

        System.out.println("before method invoke");

    }

    

    private void doAfter(){

        System.out.println("after method invoke");

    }

    

}

点击(此处)折叠或打开

public class TestMain
{

    /**

     * 测试Main方法

     * @param args

     */

    public static
void main(String
[] args){

        HelloWorld helloWorld =
new HelloWorldImpl();

        HelloWorldProxy hwp =
new HelloWorldProxy(helloWorld);

        HelloWorld proxy
= (HelloWorld)
Proxy.newProxyInstance(helloWorld.getClass().getClassLoader(),

                helloWorld.getClass().getInterfaces(),
hwp);

        proxy.sayHelloWorld();

    }

}

4、静态代理与动态代理的比较
(1)静态代理由程序员创建或工具生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。
(2)静态代理只服务于一个接口。而动态代理可以服务于多个接口。例如上述代码中的静态代理实现的是IUserDao接口,该代理类只服务于该接口,而动态代理HelloWorldProxy实现的是InvocationHandler接口,其不仅仅可以为 HelloWorld接口服务,也可为其他新增接口服务。
(3)静态代理中如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。
(4)动态代理类的源码是在程序运行期间由JVM根据反射等机制动态的生成,所以不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时确定。动态代理中的ClassLoader是类装载器类,负责将类的字节码装载到
Java 虚拟机(JVM)中并为其定义类对象,然后该类才能被使用。Proxy
静态方法生成动态代理类同样需要通过类装载器来进行装载才能使用,它与普通类的唯一区别就是其字节码是由 JVM
在运行时动态生成的而非预存在于任何一个 .class
文件中。
每次生成动态代理类对象时都需要指定一个类装载器对象.
(5)动态代理与普通的代理相比较,最大的好处是接口中声明的所有方法都被转移到一个集中的方法中处理(invoke),这样,在接口方法数量比较多的时候,我们可以进行灵活处理,而不需要像静态代理那样每一个方法进行中转。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 设计