• 23种设计模式之代理模式(静态代理)


    一:为什么学习代理模式:

      代理模式实际上是SpringAOP的底层! 【SpringAOP 和 SpringMVC (面试必问)】   

    二:代理模式(基本概念) 

      基本概念:代理模式的核心作用就是通过代理,控制对对象的访问。这跟实际中是一样的,例如说我们租房子时遇到的中介,这就是一个代理,比如有人要找中介帮忙出租房屋,那么首先处理这事的就是中介,虽然自己的房子需要出租给其他人,但是出租房子前后的一些必须要做的事(带住客看房,签订住房合同,收取租房费用)等等,都由这个中介来处理。

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

    三:那么代理模式的核心角色该如何设计呢?

      角色分析:

        ·抽象角色: 通过接口或抽象类声明真实角色实现的业务方法
    ·真实角色: 实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。(被代理的角色)它只关注真正的业务逻辑,比如拍戏。
    ·代理角色: 实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。如谈合同,布置场地等等。
    ·客户:访问代理对象的人

    四:代理模式的分类

      1、静态代理 (静态代理是我们自己创建一个代理类)   【本篇文章我们先深入了解静态代理模式,动态代理下篇文章给大家讲解】

      2、动态代理 (动态代理是程序自动帮我们生成一个代理)

    五:静态代理(来个代码看看吧)

      1、根据上面的实现步骤,首先来写一个抽象角色

    1 //租房的接口      (抽象角色)
    2 
    3 public interface Rent {
    4 
    5     void rent();
    6     
    7 }

      2、写一个真实角色(实现抽象角色类)

    1 //房东 要出租房子   (真实的角色)
    2 
    3 public class Host implements Rent {
    4     @Override
    5     public void rent() {
    6         System.out.println("房东要出租房子");
    7     }
    8 }

      3、写一个代理角色(实现抽象角色类)

     1 // 中介  帮助房东出租房子  (代理角色)
     2 
     3 public class Proxy implements Rent {
     4 
     5     //使用组合  (也可以使用继承,但java为单根继承,故有限制性,所以在这里我们使用组合的方式)
     6     private Host host;
     7 
     8     public Proxy() {
     9     }
    10 
    11     public Proxy(Host host) {
    12         this.host = host;
    13     }
    14 
    15     //代理房东出租房屋
    16     @Override
    17     public void rent() {
    18         seeHouse();
    19         host.rent();
    20         heTong();
    21         fare();
    22     }
    23 
    24     //看房
    25     public void seeHouse(){
    26         System.out.println("中介带你看房!");
    27     }
    28     //签合同
    29     public void heTong(){
    30         System.out.println("签租赁合同!");
    31     }
    32     //收中介费
    33     public void fare(){
    34         System.out.println("收中介费!");
    35     }
    36 
    37 }

      4、写一个客户   (访问代理角色的人,即需要租房子的人)

     1 // 客户  (需要租房子的人)
     2 
     3 public class Client {
     4     public static void main(String[] args) {
     5         //原始方法,在找得到房东的情况下使用, 此处学习代理模式(故需创建一个代理角色)
     6 //        Host host=new Host();
     7 //        host.rent();
     8 
     9 
    10 
    11         //代理模式
    12 
    13         //房东要出租房子
    14         Host host = new Host();
    15         //代理, 中介帮助房东出租房子,但是呢?代理角色一般会有一些附属操作(看房,签合同,收中介费等等)!
    16         Proxy proxy = new Proxy(host);
    17         //你不用面对房东,直接找中介租房子即可
    18         proxy.rent();
    19     }
    20 }

      5、输出结果为:

       由输出结果,可以看出,客户只跟代理角色(中介)打交道,代理角色就会帮真实角色(房东)需要做的事情都做了(以及一些附属操作)

    六:代理模式的好处:

        1、可以使真实角色的操作更加纯粹!就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一切事务,附带的结果就是编程简洁清晰。
    2、公共业务就交给代理角色!实现了业务的分工!代理角色可以在客户端和目标对象之间起到中介的作用,这样起到了中介的作用和保护了目标对象的作用。
    3、公共业务发生扩展的时候,方便集中管理 (高扩展性)
     缺点:
    1、一个真实角色就会产生一个代理角色;代码量会翻倍---开发效率会变低

    七:针对代理模式的高扩展性进行(加深理解)
      
    (代码示例)
    在不改变原有业务的情况下,扩展一些功能 (本示例为: 扩展日志功能)


      1、抽象角色
    1 //抽象角色
    2 public interface UserService {
    3 
    4     void add();
    5     void delete();
    6     void update();
    7     void query();
    8 }

      2、真实角色

     1 //真实角色
     2 
     3 public class UserServiceImpl implements UserService {
     4     @Override
     5     public void add() {
     6         System.out.println("增加了一个用户");
     7     }
     8 
     9     @Override
    10     public void delete() {
    11         System.out.println("删除了一个用户");
    12     }
    13 
    14     @Override
    15     public void update() {
    16         System.out.println("修改了一个用户");
    17     }
    18 
    19     @Override
    20     public void query() {
    21         System.out.println("查询了一个用户");
    22     }
    23 
    24 }

      3、代理角色

     1 //在不改变原有业务的情况下,扩展一些功能  (本示例为: 扩展日志功能)
     2 
     3 public class UserServiceProxy implements UserService {
     4 
     5     private UserServiceImpl userService;
     6 
     7     //Spring 中不建议使用 有参构造组合
     8 //    public UserServiceProxy(UserServiceImpl userService) {
     9 //        this.userService = userService;
    10 //    }
    11 
    12     //Spring 中注入一个对象,建议使用set方法
    13     public void setUserService(UserServiceImpl userService) {
    14         this.userService = userService;
    15     }
    16 
    17     @Override
    18     public void add() {
    19         log("add");
    20         userService.add();
    21     }
    22 
    23     @Override
    24     public void delete() {
    25         log("delete");
    26         userService.delete();
    27     }
    28 
    29     @Override
    30     public void update() {
    31         log("update");
    32         userService.update();
    33     }
    34 
    35     @Override
    36     public void query() {
    37         log("query");
    38         userService.query();
    39     }
    40 
    41     //日志方法
    42     public void log(String msg){
    43         System.out.println("[Debug] 使用了"+msg+"方法");
    44     }
    45 }

      4、客户 (测试类)

     1 //测试类
     2 
     3 public class Client {
     4     public static void main(String[] args) {
     5         //真实角色
     6         UserServiceImpl userService=new UserServiceImpl();
     7         //代理角色
     8         UserServiceProxy proxy=new UserServiceProxy();
     9         //代理真实角色 userService
    10         proxy.setUserService(userService);
    11         //代理实现查询方法
    12         proxy.query();
    13     }
    14 }

      5、输出结果:

     

      注: 大家针对 AOP 做一定深度的了解,了解代理模式底层,以及对 SpringAOP 和 SpringMVC 的使用 (面试高频问)

                下篇文章我们继续解读    【动态代理模式】



  • 相关阅读:
    数据切分——Mysql分区表的建立及性能分析
    MySQL性能优化的21个最佳实践 和 mysql使用索引
    MySQL性能优化的21个最佳实践 和 mysql使用索引
    mysql分表的3种方法
    mysql分表的3种方法
    css3基本属性
    elemet-ui图标—特殊字符的unicode编码表
    css属性之统一设置文本及div之间的对齐方式
    vue-cli创建项目
    element-ui修改全局样式且只作用于当前页面
  • 原文地址:https://www.cnblogs.com/liangbaolong/p/13341837.html
Copyright © 2020-2023  润新知