`

结构型-代理模式

 
阅读更多

定义

为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

UML

 

抽象角色:通过接口或抽象类声明真实角色实现的业务方法。

代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。(最简单的比如打印日志)

真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。

 

实例

代理商,本身不生成产品,但是从厂家拿产品卖个用户。起到媒介作用。

java的代理模式

简单demo:

/**
 * 抽象主题,定义主要功能
 */
publicinterface Subject {
   publicvoid operate();
}
/**
 * 具体主题
 */
publicclass RealSubject implements Subject{
   @Override
   publicvoid operate() {
        System.out.println("realsubject operatestarted......");
   }
}
/**
 * 代理类
 */
publicclass Proxy implements Subject{
   private Subject subject;
   public Proxy(Subject subject) {
        this.subject = subject;
   }
   @Override
   publicvoid operate() {
        System.out.println("before operate......");
        subject.operate();
        System.out.println("after operate......");
   }
}
public class Client {
   publicstaticvoid main(String[] args) {
        Subject subject = new RealSubject();
        Proxy proxy = new Proxy(subject);
        proxy.operate();
   }
}

 

动态代理

import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Proxy;
 import java.lang.reflect.Method;
 //抽象角色:java动态代理的实现目前只支持接口,不支持抽象类
 interface BusinessFoo
 {
     void foo();
 }
 interface BusinessBar
{
    String bar(String message);
}
//真实角色:真正实现业务逻辑方法
class BusinessFooImpl implements BusinessFoo
{
    public void foo()
    {
        System.out.println("BusinessFooImpl.foo()");
    }
}
class BusinessBarImpl implements BusinessBar
{
    public String bar(String message)
    {
        System.out.println("BusinessBarImpl.bar()");
        return message;
    }
}
//动态角色:动态生成代理类
class BusinessImplProxy implements InvocationHandler
{
    private Object obj;
    BusinessImplProxy() {
    }
    BusinessImplProxy(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;
    }
    public void doBefore(){
        System.out.println("do something before Business Logic");
    }
    public void doAfter(){
        System.out.println("do something after Business Logic");
    }
    public static Object factory(Object obj)
    {
        Class cls = obj.getClass();
        return Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),new BusinessImplProxy(obj));
    }
}
//测试类
public class DynamicProxy
{    
    public static void main(String[] args) throws Throwable
    {
        BusinessFooImpl bfoo = new BusinessFooImpl();
        BusinessFoo bf = (BusinessFoo)BusinessImplProxy.factory(bfoo);
        bf.foo();
        System.out.println();
        
        BusinessBarImpl bbar = new BusinessBarImpl();
        BusinessBar bb = (BusinessBar)BusinessImplProxy.factory(bbar);
        String message = bb.bar("Hello,World");
        System.out.println(message);
    }
}

优点

(1).职责清晰真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件完成事务,附带的结果就是编程简洁清晰。

(2).代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了的作用和保护了目标对象的作用。

(3).高扩展性

 

比较

代理模式与外观模式的区别:

1、外观模式也是屏蔽复杂性的,但是外观模式不会实现客户端调用的目标类型接口。

2、一般客户端调用外观模式的方法都是直接调用。

3、代理模式中对客户端目标对象类型抽象接口具体化了。

4、外观模式是代理模式中一种特殊的子级模式(广泛的,非约束性)。

 

代理模式与适配器模式区别

适配器为它所适配的对象提供了一个不同的接口。相反,代理提供了与它的实体相同的接口。然而,用于访问保护的代理可能会拒绝执行实体会执行的操作,

因此,它的接口实际上可能只是实体接口的一个子集。

 

代理模式与装饰器模式区别

尽管装饰器的实现部分与代理相似,但装饰器的目的不一样。装饰器为对象添加一个或多个功能,而代理则控制对对象的访问。

 

  • 大小: 10.5 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics