代理模式

 

 

    1.1 静态代理

             •  抽象角色:一般会使用接口或者抽象来解决

             •  真实角色:被代理的角色

             •  代理角色: 代理真实角色,代理真实角色后,我们一般会做一些附属操作

             •  客户:访问代理的人!     

    真实类:

//房东
public class Host implements Rent {


    public void rent() {
        System.out.println("房东要组房");
    }
}

    抽象角色:接口

//租房
public interface Rent {
    public void rent();

}

      代理角色:

     

//中介
public class Proxy  implements Rent{
    private  Host host;

    public Proxy(Host host) {
        this.host = host;
    }

    public Proxy() {
    }

    public void rent() {
       seeHouse();
        host.rent();
       free();
    }
    //看房
    public void seeHouse(){
        System.out.println("中介看房");
    }

    //收中介费
    public void free(){
        System.out.println("中介收中介费");
    }
}

      客户:

public class Client {
    public static void main(String[] args) {
        Host host =new Host();
        //代理  中介帮房东看房子
        Proxy proxy = new Proxy(host);
        //不用找房东  直接找中介  直接接触中介
        proxy.rent();
    }

}

        租客租房不用面对房东,直接找中介租房即可!

  代理模式的好处:
        •  可以使真实角色的操作更加纯粹!不用去关注一些公共的业务

        •  公共业务交给代理角色!实现了业务的分工!

        •  公共业务发生扩展的时候,方便集中管理!

     缺点:

       •  一个则真实角色就会产生一个代理角色,代码量会翻倍,开发效率会变低。 

       使用静态代理加入日志

        真实类:

//真实对象
public class UserServiceImpl implements UserService{
    public void add() {
        System.out.println("增加一个用户");
    }

    public void delete() {
        System.out.println("删除一个用户");
    }

    public void update() {
        System.out.println("修改一个用户");
    }

    public void find() {
        System.out.println("查找一个用户");
    }
}

      抽象角色:

//抽象角色
public interface UserService {
    public void add();
    public void delete();
    public void update();
    public void find();
}

      代理对象

//代理对象
public class UserServiceProxy implements UserService {

    private UserServiceImpl userService;

    public void setUserService(UserServiceImpl userService) {
        this.userService = userService;
    }

    public void add() {
        log("add");
        userService.add();
    }

    public void delete() {
        log("delete");
        userService.delete();
    }

    public void update() {
        log("update");
         userService.update();
    }

    public void find() {
        log("find");
        userService.find();
    }
    //加入日志功能,在实现真实类的操作前,记录日志
    public void log(String msg){
        System.out.println("使用了"+msg+"方法");
    }
    
}

    客户

public class Client {
    public static void main(String[] args) {
        UserServiceImpl impl=new UserServiceImpl();
        UserServiceProxy proxy=new UserServiceProxy();
        proxy.setUserService(impl);
        proxy.add();
    }
}

 1.2 动态代理

           

 

   使用动态代理租房:

         真实类:     

//房东
public class Host implements Rent {
    public void rent() {
        System.out.println("房东要组房");
    }
}

       抽象角色:

//租房
public interface Rent {
    public void rent();

}

     代理角色:

//会用这个类自动生成代理
public class ProxyInvocationHandler implements InvocationHandler {

    private Rent rent;
    public  void setRent(Rent rent){
        this.rent=rent;
    }



    //生成代理类
    public  Object getProxy(){
      return   Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this);
    }

    //处理代理实例 ,返回结果
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
seeHouse();
        ///c处理动态类的本质,就是反射机制
        Object result = method.invoke(rent, args);
free();
        return result;
    }
    public void seeHouse(){
        System.out.println("中介看房子");
    }
    public void free(){
        System.out.println("中介收费");
    }

}

      客户:

public class Client {
    public static void main(String[] args) {
    //真实角色
        Host host=new Host();
        //代理教角色,现在没有
        ProxyInvocationHandler proxyInvocationHandler=new ProxyInvocationHandler();
        //通过调用程序处理角色来处理我们要调用的接口对象
        proxyInvocationHandler.setRent(host);
       //这里的proxy就是动态生成的,我们并没有写
        Rent proxy =(Rent) proxyInvocationHandler.getProxy();
       proxy.rent();
    }

}

   使用动态代理生成日志:

    代理对象: 可当作模板

//会用这个类自动生成代理
public class ProxyInvocationHandler implements InvocationHandler {

    private Object target;
    public  void setTarget(Object target){
        this.target=target;
    }

    //生成代理类
    public  Object getProxy(){
      return   Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    }

    //处理代理实例 ,返回结果
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        log(method.getName());
        ///c处理动态类的本质,就是反射机制
        Object result = method.invoke(target, args);
        return result;
    }
    public void log(String msg){
        System.out.println("执行力"+msg+"方法");
    }
}

    客户:

public class Client {
    public static void main(String[] args) {
        //真实角色
        UserServiceImpl userService =new UserServiceImpl();
        //代理角色 不存在
        ProxyInvocationHandler pih=  new ProxyInvocationHandler();
       //设置要代理的对象
        pih.setTarget(userService);
        //动态生成代理类
        UserService proxy=(UserService) pih.getProxy();
        proxy.add();

    }
}  

   动态代理的好处:

       •  可以使用真实角色的操作更加纯粹! 不用去关注一些的公共业务

       •  公共业务就交给代理角色! 实现了业务的分工!

       •  公共业务发生扩展的时候,方便集中管理!

       •  一个动态代理类代理的是一个接口,一般就是对应的一类业务

       •  一个动态代理可以代理多个类,只要是实现了同一个接口即可!

 

 

 

 

 

 

 

 

 

 

 

  

 

posted @ 2021-03-01 11:15  coline  阅读(122)  评论(0)    收藏  举报