设计模式之代理模式

时间:2022-09-09 08:32:51

1. 定义:为其他对象提供一种代理以控制对这个对象的访问。Provide a surrogate or placeholder for another object to control access to it.

2. 简单示例代码

public interface  DBOperation {     //定义最高抽象的接口,此接口定义了对一个数据库表的一些操作。
public boolean add();
public boolean delete();
public boolean update();
public boolean select();
}
import java.sql.Connection;import java.sql.DriverManager;public class DBOProxy implements DBOperation{  //代理类 实现上述接口,但是具体的逻辑要由真实类实现。                                               //代理类可以使得高层调用不发生修改的情况下,可以修改被代理类的实现逻辑。private static Connection conn=null;   //创建一个数据库的连接,此处并没有实际数据库连接。private DBOperation obj=null;          //代理类中可以为真实类提供 共有的属性 比如一个数据库连接。public DBOProxy(){                //构造函数中从外部传入一个被代理对象,或者调用默认被代理对象  this(new DBOpimpl(conn));     }public DBOProxy(DBOperation dbo) {this.obj=dbo;}private static int count=0;public void Count()              //代理类可以提供 自己所有的方法 用于统计真实类的调用情况等。{System.out.println("我已经代理处理"+count+"个方法了,累死了");}/* * public boolean add() {if(obj==null)obj=new DBOpimpl(conn);  //实现延迟加载 在实际调用的时候才产生真实类return obj.add();            //这样在每个方法里面都需要增加判断代码} * */@Overridepublic boolean add() {// TODO Auto-generated method stubcount++;if(obj.add())return true;return false;}@Overridepublic boolean delete() {// TODO Auto-generated method stubcount++;if(obj.delete())return true;return false;}@Overridepublic boolean update() {// TODO Auto-generated method stubcount++;if(obj.update())return true;return false;}@Overridepublic boolean select() {// TODO Auto-generated method stubcount++;if (obj.select())return true;return false;}}public class DBOpimpl implements DBOperation {     //真实类,可以实现特有的逻辑    private Connection conn=null;        public DBOpimpl(Connection conn) {        // TODO Auto-generated constructor stub        this.conn=conn;    }        @Override    public boolean add() {        // TODO Auto-generated method stub        System.out.println("增加成功");        return true;    }    @Override    public boolean delete() {        // TODO Auto-generated method stub        System.out.println("删除成功");        return true;    }    @Override    public boolean update() {        // TODO Auto-generated method stub        System.out.println("更新成功");        return true;    }    @Override    public boolean select() {        // TODO Auto-generated method stub        System.out.println("查询成功");        return true;    }}
 System.out.println("************代理模式************");         DBOperation proxy=new DBOProxy();         proxy.add();************代理模式************增加成功
3. 指定代理示例
public class Designateimpl implements DBOperation{   //由 真实类 指定能调用自己的代理,其他未指定的代理类都无法调用自己。
private Connection conn=null;

public Designateimpl(Connection conn) {
// TODO Auto-generated constructor stub
this.conn=conn;
}

private DBOProxy proxy=null;

public DBOProxy getProxy(){ //自己指定代理后 返回此代理的引用
this.proxy=new DBOProxy(this); //此处指定的代理 还是上面的代理
return this.proxy;
}

    private boolean isProxy()
    {
        if (this.proxy==null)
            return false;
        else
            return true;
    }
    @Override
    public boolean add() {
        // TODO Auto-generated method stub
        if(isProxy()) //只有通过自己的代理 才能访问真实类的方法。
        {
            System.out.println("增加成功");
            return true;
        }
        else
        {
            System.out.println("增加失败,请使用我的代理");
              return false;
        }
    }

    @Override
    public boolean delete() {
        // TODO Auto-generated method stub
        if(isProxy())
        {
            System.out.println("删除成功");
            return true;
        }
        else
        {
            System.out.println("删除失败,请使用我的代理");
              return false;
        }
    }

    @Override
    public boolean update() {
        // TODO Auto-generated method stub
        if(isProxy())
        {
            System.out.println("更新成功");
            return true;
        }
        else
        {
            System.out.println("更新失败,请使用我的代理");
              return false;
        }
    }

    @Override
    public boolean select() {
        // TODO Auto-generated method stub
        if(isProxy())
        {
            System.out.println("查询成功");
            return true;
        }
        else
        {
            System.out.println("查询失败,请使用我的代理");
              return false;
        }
    }
}
DBOProxy proxy21=new DBOProxy(new Designateimpl(null));         DBOProxy proxy2=new Designateimpl(null).getProxy();         proxy21.delete();proxy21.Count();         proxy2.delete();proxy2.Count();//此处 前面调用了一次add()方法所以处理了2次。  从结果可知,由于前面一个未使用指定的代理所以调用失败,而后面一个使用了指定的代理 调用成功删除失败,请使用我的代理我已经代理处理2个方法了,累死了删除成功我已经代理处理3个方法了,累死了
4. 动态代理示例
public class DynamicProxy implements InvocationHandler{

DBOperation obj=null; //

public DynamicProxy(DBOperation obj) {
// TODO Auto-generated constructor stub
this.obj=obj;
}

public DBOperation getProxy() //返回动态代理实例
{ //指定真实类加载器、调用的接口方法(注意真实类一定要继承自某个接口) 和实现了InvocationHandler接口的动态代理类。
return (DBOperation) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
//此处返回的类型为接口类型,返回类类型时会产生ClassCast异常
 }
//实现InvocationHandler接口的invoke方法,指定代理的实例将调用的方法和参数,并将结果返回。
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
System.out.println("动态代理发生调用,生人回避");
return method.invoke(this.obj, args); //通过委托调用指定类中的方法。
}

}
 DBOperation dbo=new DBOpimpl(null);   //动态代理绑定的真实类         DBOperation proxy3= new DynamicProxy(dbo).getProxy();  //获得动态代理实例         proxy3.select();proxy3.update();  //动态代理调用动态代理发生调用,生人回避查询成功动态代理发生调用,生人回避更新成功