代理模式——静态代理(贴近业务)

2023-11-10

静态代理概念:所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了,通常用于对原有业务逻辑的扩充。

举例理解:以结婚为例,当事人只需要处理自己的主要事儿即可,比如典礼、洞房,其他的杂事儿可以交给代理公司即可

静态代理需要满足三点:

1、需要有真实角色

2、需要有一个代理角色

3、这两个角色之间必须实现相同的接口

静态代理类优缺点
优点:1,可以使真实角色的操作更加纯粹!不用去关注一些公共的业务。2,公共也就交给代理角色!实现了业务的分工。3,公共业务发生扩展的时候,方便集中管理!
缺点:1,代理对象的一个接口只服务于一种类型的对象,如果要代理的接口很多,势必要为每一个接口都进行代理,势必会新增很多代理类,静态代理在程序规模稍大时就无法胜任了。2,如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。

public interface UserService {
    public void add();
    public void select();
    public void delect();
}
public class UserServiceImp implements UserService{
    @Override
    public void add() {
        System.out.println("执行的添加方法");
    }
    @Override
    public void select() {
        System.out.println("执行的查询方法");
    }
    @Override
    public void delect() {
        System.out.println("执行的删除方法");
    }
}

比如现在有这么个业务。service出问题了项目经理需要你跟service添加一个日志方法,你可能立马会想到在原有的类上面做添加日志方法的操作,但是如果这类不是你写的,代码量有比较多,万一添加后代码蹦了呢,其次这也不满足开闭原则。因为改动了原由代码。

public class UserServiceImp implements UserService{
    @Override
    public void add() {
        System.out.println("日志记录了添加方法");
        System.out.println("执行的添加方法");
    }
    @Override
    public void select() {
        System.out.println("日志记录了查询方法");
        System.out.println("执行的查询方法");
    }
    @Override
    public void delect() {
        System.out.println("日志记录了删除方法");
        System.out.println("执行的删除方法");
    }
}

这样做肯定是不行的,这时我们就可以采用代理模式来做 新增一个代理类也去实现UserService

public class UserServiceProxy implements UserService {
    private UserServiceImp userServiceImp;

    public void setUserServiceImp(UserServiceImp userServiceImp) {
        this.userServiceImp = userServiceImp;
    }
    @Override
    public void add() {
        log();
        userServiceImp.add();
    }
    @Override
    public void select() {
        log();
        userServiceImp.select();
    }
    @Override
    public void delect() {
        log();
        userServiceImp.select();
    }
    //日志方法
    public void log(){
        System.out.println("打印了日志");
    }
}

class Test{
    public static void main(String[] args) {
        UserServiceImp userServiceImp = new UserServiceImp();
        UserServiceProxy userServiceProxy = new UserServiceProxy();
        userServiceProxy.setUserServiceImp(userServiceImp);;
        userServiceProxy.add();
    }

}

这样子我们可以为想要的UserServiceImp 方法添加日志,即没有修改原由代码,这样子符合开闭原则

在Java中线程的设计就使用了静态代理设计模式,其中自定义线程类实现Runable接口,Thread类也实现了Runalbe接口,在创建子线程的时候,传入了自定义线程类的引用,再通过调用start()方法,调用自定义线程对象的run()方法。实现了线程的并发执行。

public class Test2 {
     public static void main(String[] args) {
          //Runnable实现类对象,真实角色
          Thread1 role1 = new Thread1();
          //线程类代理角色,该类也实现了Runnable接口,代理角色
          Thread thread1 = new Thread(role1);//传入了真实角色的引用      
          thread1.start();  
     }
 }
 
class Thread1 implements Runnable {
     @Override
     public void run() {
         //TODO
     }
 }

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

代理模式——静态代理(贴近业务) 的相关文章

随机推荐

  • 【2023持续更新】网络安全工程师常用网站集合

    文章目录 信息搜集 子域名搜集 在线工具 信息处理 威胁情报及分析 在线靶场 综合学习 安全资讯技术 大会演讲PPT 安全社区 社工工程学 信息搜集 http www yunsee cn http finger tidesec com ht
  • Vue.js子级向父级传递数据

    组件之间的数据的传递 子传父 注意 html对大小写不敏感 事件名字最好用 隔开或全部小写 步骤 1 在父组件中在子组件上添加事件 自定义 监听 代表的含意 事件分两类 浏览器自带的事件 click mouseover mousedown
  • 11-2_Qt 5.9 C++开发指南_QSqlQueryModel的使用(QSqlQueryModel 只能作为只读数据源使用,不可以编辑数据)

    文章目录 1 QSqlQueryModel 功能概述 2 使用 QSqlQueryModel 实现数据查询 2 1 实例功能 2 2 可视化UI设计 2 3 主窗口类定义 去除自动生成的槽函数 2 4 打开数据库 2 5 记录移动 1 QS
  • java.lang.ClassCastException: java.math.BigDecimal cannot be cast to java.lang.Integer

    因为BigDecimal不能强制转换成 String类型 要用toString 作为中间桥梁转换 同理 Object BigDecimal转换成int doulbe long 也是一样的 List
  • 灰灰-判断是否存在重复数

    给定一个整数数组 判断是否存在重复元素 如果任何值在数组中出现至少两次 函数返回 true 如果数组中每个元素都不相同 则返回 false 示例 1 输入 1 2 3 1 输出 true 示例 2 输入 1 2 3 4 输出 false 示
  • QT笔记——QTableWidget 之 指定某列排序

    指定某列共有2种方式 1 重写 bool QTableWidgetItem operator lt const QTableWidgetItem other const 2 点击表头进行排序 connect ui tableWidget g
  • Python配置第三方库最全教程

    学Python最让人头疼的莫过于去配置一大堆杂乱的第三方库 而下载第三方库时报错也能让你崩溃 今天 我整理了一份全的教程 最常用的办法下载第三方库 在终端中执行 pip install 第三方库名称 大部分人一般不会报错 但偏偏我去安装最基
  • fbmem驱动框架分析

    文章目录 fbmem驱动框架分析 1 与misc驱动框架类比 1 1 my first cdev的记录 1 2 关于misc驱动框架的总结 2 fbmem驱动框架 2 1提供注册函数 2 2 操作函数分析 2 2 1 open函数分析 op
  • google analytics 添加跟踪代码

    google analytics添加跟踪代码实现统计分析 其代码添加方式共有三种 1 gtag js 基础代码
  • 个人网站搭建 04——WebHooks 实现远程项目的自动部署

    环境说明 Github 或 Gitee 维护的网站代码 支持 Webhooks 由于 Github 访问速度受限 易出现超时问题 我使用 Gitee 部署代码 Linux 公网服务器 阿里云 腾讯云 华为云等 服务器操作环境为 CentOS
  • Windows环境下 Redis RDB持久化无法生成dump.rdb文件

    Windows环境下 Redis RDB持久化无法生成dump rdb文件 问题 删除dump rdb文件 配置redis windows conf的SNAPSHOTTING 设置在60秒内进行了5次操作 即写入rdb文件中进行持久化保存
  • spring cloud 版本错Cannot resolve org.springframework.cloud:spring-cloud-starter-openfeign:unknown

    Cannot resolve org springframework cloud spring cloud starter openfeign unknown 说明 创建spring cloud项目后依赖错误 原因 版本错误 如下图 有些博
  • 怎么进入项目后台服务器,项目部署并常驻在服务器后台

    前言 上一次文章是自己的博客项目正式上线 这次分享 怎么让自己写好的项目常驻与服务器后台 在这之前 先了解一下服务器部署项目的一些环境依赖问题 服务器部署项目时 你的项目用到了什么环境 就要在服务器上安装相应的环境依赖 一般常要安装的就是M
  • 二进制颜色代码大全(含图)

    二进制颜色代码大全 可供大家开发时参考 FFFFFF DDDDDD AAAAAA 888888 666666 444444 000000 FFB7DD FF88C2 FF44AA FF0088 C10066 A20055 8C0044 FF
  • 如何证明凸函数的局部极小值为全局极小值

    最近上系统分析这门课的时候 老师提到了这个概念 当我们能够确定凸函数的局部最小值 这个最小值即为全局极小值 但并未给出证明 这里记录一下 主要用的还是凸函数的定义 凸函数区间任意位置的函数值小于两区间端点函数值之和
  • c#客户端Kafka的使用方法

    简介 Apache Kafka是一个分布式流处理平台 最初由LinkedIn开发 现在是Apache软件基金会的顶级项目之一 Kafka能够处理大规模的实时数据流 支持高可靠性 高可扩展性 低延迟和高吞吐量 它主要用于构建实时数据管道和流式
  • Pycharm debug 的使用

    Debug 作用的理解 若整个代码编写没有错误 且执行体没有设置断点时 Debug同正常运行模式 直接得到最终结果 当某一行代码设置断点后 在Debug模式下 代码会运行断点之前的所有程序 在断点处暂停 并在 变量窗口 可以查看所有主程序当
  • C#学习笔记:RadioButton控件与CheckBox控件的用法

    一 用途 1 RadioButton控件 单选按钮 当与其他单选按钮成对出现时 允许用户从一组选项中选择单个选项 也就是说 当同一个容器中 Form Panel GroupBox PictureBox等 存在两个以上的单选按钮时 只能有一个
  • C#对象和类--习题(1)

    1 一个景区根据游人的年龄收取不同价格的门票 请编写游人类 根据年龄段决定能够购买门票价格并输出 class XiTi string name int age void Xiti1 for 死循环 类似的while true Console
  • 代理模式——静态代理(贴近业务)

    静态代理概念 所谓静态也就是在程序运行前就已经存在代理类的字节码文件 代理类和委托类的关系在运行前就确定了 通常用于对原有业务逻辑的扩充 举例理解 以结婚为例 当事人只需要处理自己的主要事儿即可 比如典礼 洞房 其他的杂事儿可以交给代理公司