BCSP-玄子Share-Java框基础_工厂模式/代理模式

news2024/12/24 8:40:18

三、设计模式

3.1 设计模式简介

  • 软件设计中的三十六计
  • 是人们在长期的软件开发中的经验总结
  • 是对某些特定问题的经过实践检验的特定解决方法
  • 被广泛运用在 Java 框架技术中

3.1.1 设计模式的优点

  • 设计模式是可复用的面向对象软件的基础
  • 可以更加简单方便地复用成功的设计和体系结构
  • 帮助开发者做出有利于系统复用的选择,避免损害系统复用性的设计
  • 使其他开发者更加容易理解其设计思路,便于团队交流

3.1.2 设计模式分类

GoF(Gang of Four,四人组)设计模式分为23种

范围/目的创建型模式结构型模式行为型模式
类模式工厂方法(类)适配器模板方法解释器
对象模式单例
原型
抽象工厂
建造者
代理
(对象)适配器
桥接
装饰
外观
享元
组合
策略
命令
职责链
状态
观察者
中介者
迭代器
访问者
备忘录

3.1.3 面向对象设计原则

单一职责原则

  • 一个类应该有且仅有一个引起它变化的原因
  • 一个类应该只负责一个职责

开闭原则

  • 对扩展开放,对修改关闭

里氏替换原则

  • 引用基类的地方必须能透明地使用其子类的对象
  • 可以用来判断继承关系是否合理

依赖倒置原则

  • 依赖于抽象而不依赖于具体实现,针对接口编程

接口隔离原则

  • 尽量将庞大臃肿的接口拆分成更小更具体的接口
  • 接口中只包含客户感兴趣的方法

迪米特法则

  • 又称最少知道原则
  • 一个软件实体应当尽可能少地与其他实体发生相互作用

合成复用原则

  • 尽量使用组合/聚合的方式而不是继承关系达到软件复用的目的
  • 是 has-a 关系

3.2 简单工厂模式

如何解决类似“Service与某个具体Dao实现”耦合的问题?

将创建工作转移出来避免在Service中创建具体的Dao实现类,产生耦合

简单工厂模式,又叫做静态工厂方法模式,不属于 GoF 的23种设计模式之一,可以理解为工厂模式的一个特殊实现

3.2.1 简单工厂模式+依赖倒置原则

依据依赖倒置原则,使用setter方法传递依赖关系,减少Service对工厂类的依赖,降低耦合

public class NewsServiceImpl implements NewsService {
	private NewsDao dao;
	public void setDao(NewsDao dao) {
		this.dao = dao;
	}
	… …
}

3.2.2 简单工厂+参数

简单工厂模式可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类

// 创建NewsDao实例的工厂方法
public static NewsDao getInstance(String key) {
    switch (key) {
        case "mysql":
            return new NewsDaoMySqlImpl();
        case "oracle":
            return new NewsDaoOracleImpl();
        case "redis":
            return new NewsDaoRedisImpl();
        default:
            throw new RuntimeException("无效的数据库类型:" + key + " ,DAO获取失败");
    }
}

要创建的产品不多且逻辑不复杂的情况,可以考虑简单工厂模式

简单工厂模式包含如下角色

  • 工厂(Factory)
  • 抽象产品(Product)
  • 具体产品(Concrete Product)

增加新的产品需要修改,工厂方法的判断逻辑,不符合开闭原则


3.3 工厂方法模式

3.3.1 实现方式

对简单工厂模式的进一步抽象,工厂方法模式的主要角色如下

  • 抽象产品(Product)
  • 抽象工厂(Abstract Factory)
  • 具体产品(Concrete Product)
  • 具体工厂(Concrete Factory)

3.3.2 代码案例

创建抽象工厂接口

public interface AbstractFactory {
    public NewsDao getInstance();
}

为不同NewsDao实现创建相对应的具体工厂

// 以生产NewsDaoMySqlImpl实例的工厂为例
public class MySqlDaoFactory implements AbstractFactory {
    @Override
    public NewsDao getInstance() {
        return new NewsDaoMySqlImpl();
    }
}

在测试方法中通过特定工厂生产相关的NewsDao实例

AbstractFactory factory = new MySqlDaoFactory(); 
// 改变具体工厂可创建不同产品
NewsDao dao = factory.getInstance();

3.3.3 优缺点

优点

  • 只需要知道具体工厂就可得到所要的产品,无须知道产品的具体创建过程
  • 基于多态,便于对复杂逻辑进行封装管理
  • 增加新的产品时无须对原工厂进行任何修改,满足开闭原则

缺点

  • 每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度

3.4 代理设计模式

单一职责原则的体现,包含如下角色

  • 抽象主题(Subject)
  • 真实主题(Real Subject)
  • 代理(Proxy)

实现方式总体上分为静态代理和动态代理

  • 静态代理由开发者针对抽象主题编写相关的代理类实现,编译之后生成代理类的class文件
  • 动态代理是在运行时动态生成的,在运行时动态生成代理类字节码

3.4.1 基于接口的静态代理实现

// 抽象主题接口 - 图片
public interface Image {
    void display();
}

// 真实主题类 - 真实图片
public class RealImage implements Image {
    private String filename;

    public RealImage(String filename) {
        this.filename = filename;
        loadImageFromDisk();
    }

    private void loadImageFromDisk() {
        System.out.println("Loading image from disk: " + filename);
    }

    public void display() {
        System.out.println("Displaying image: " + filename);
    }
}

// 代理类 - 图片代理
public class ImageProxy implements Image {
    private RealImage realImage;
    private String filename;

    public ImageProxy(String filename) {
        this.filename = filename;
    }

    public void display() {
        if (realImage == null) {
            realImage = new RealImage(filename);
        }
        realImage.display();
    }
}

// 调用代码
public class Client {
    public static void main(String[] args) {
        // 创建代理对象并显示图片
        Image image = new ImageProxy("example.jpg");
        image.display();
    }
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3.4.2 代理模式优点分析

  • 代理模式将客户与目标对象分离,在一定程度上降低了系统的耦合度
  • 代理对象可以对目标对象的功能进行扩展,目标对象和扩展功能职责清晰且不会产生耦合

3.4.3 动态代理

静态代理需要手工编写代理类,存在以下弊端

  • 目标对象API发生变化,代理类也必须进行修改,增加工作量且不符合开闭原则
  • 通过继承得到的代理类只能对一种类型进行代理,组件较多时,代理类的开发工作量巨大
  • 动态代理提供了运行时动态扩展对象行为的能力
  • 能够依据给定的业务规则,在运行时动态生成代理类

3.4.4 JDK 动态代理

从JDK 1.3版本开始引入

是面向接口的代理实现

  • 要求被代理的目标对象必须通过抽象主题接口进行定义

核心API

  • java.lang.reflect.InvocationHandler接口
    • 代理方法的调用处理程序,负责为代理方法提供业务逻辑
    • 包含方法:Object invoke(Object proxy, Method method, Object[] args)
  • java.lang.reflect.Proxy类
    • 负责动态创建代理类及其实例
    • 主要方法:static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)

3.4.5 CGLIB 动态代理

如果被代理的目标对象不是通过接口进行定义的,JDK 动态代理将无法实施

  • CGLIB(Code Generation Library)是一个功能强大,高性能的代码生成库
  • 可以为没有实现接口的类提供代理,原理是为需要代理的类动态生成一个子类作为其代理类

需要使用继承和重写机制,CGLIB动态代理对于final类或final方法无能为力

从cglib https://github.com/cglib/cglib/releases下载所需的 jar 文件

  • cglib-nodep-x.x.x.jar

主要 API

  • net.sf.cglib.proxy.MethodInterceptor 接口
    • 负责拦截父类的方法调用,以便加入代理的业务逻辑
    • 包含方法
      • Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)
  • net.sf.cglib.proxy.Enhancer 类
    • 负责动态创建代理类及其实例
    • 主要方法
      • setSupperclass()
      • setCallback()
      • set…
      • create()

3.4.6 JDK 和 CGLIB 动态代理的对比

  • JDK 动态代理面向接口代理,只能对基于接口设计的目标对象进行代理
  • CGLIB 动态代理可以通过继承方式实现,不依赖接口,但是不能代理 final 的类和方法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/972834.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【管理运筹学】第 7 章 | 图与网络分析(2,最小支撑树问题)

文章目录 引言二、最小支撑树问题2.1 树的定义及其基本性质2.2 图的支撑树2.3 最小支撑树的定义及有关定理2.4 最小支撑树算法2.4.1 避圈法&#xff08;KRUSKAL算法&#xff09;2.4.2 反圈法&#xff08;PRIM算法&#xff09;2.4.3 破圈法 写在最后 引言 承接前文&#xff0c;…

宠物电商Chewy第二季度销售额28亿美元,同比增长14.3%

美国宠物电商Chewy公布2023年第二季度财报。报告显示&#xff0c;其Q2季度销售额同比增长14.3%至28亿美元&#xff0c;超出市场预期。 以下为Chewy期内业绩概要&#xff1a; 1.毛利率28.3%&#xff0c;同比增长20个基点 2.净利润有所收窄&#xff0c;同比下降15.2%至1890万美…

QT连接数据库

目录 数据库 数据库基本概念 常用的数据库 SQLite3基础 SQLite特性&#xff1a; QT连接数据库 1.1 QT将数据库分为三个层次 1.2 实现数据库操作的相关方法 sql语句&#xff08;常用&#xff09; 1&#xff09;创建表格 2&#xff09;删除表格 3&#xff09;插入记录 …

应急物资管理系统DW-S300|助力应急物资保障体系建设

国务院新闻办公室于2023年7月25日举行国务院政策例行吹风会&#xff0c;介绍防汛抗旱工作情况&#xff0c;并答记者问。应急管理部副部长、水利部副部长王道席介绍&#xff0c;要推进应急物资保障体系建设。去年&#xff0c;应急管理部会同国家发展改革委、财政部、国家粮食和物…

AIGC专栏5——EasyPhoto AI写真照片生成器 sd-webui插件介绍、安装与使用

AIGC专栏5——EasyPhoto AI写真照片生成器 插件安装与使用 学习前言源码下载地址技术原理储备&#xff08;SD/Control/Lora&#xff09;StableDiffusionControlNetLora EasyPhoto插件简介EasyPhoto插件安装安装方式一&#xff1a;Webui界面安装 &#xff08;需要良好的网络&…

Linux监测进程打开文件

分析问题过程中&#xff0c;追踪进程打开的文件可以在许多不同情况下有用&#xff0c;体现在以下几个方面&#xff1a; 故障排除和调试&#xff1a; 当程序出现问题、崩溃或异常行为时&#xff0c;追踪进程打开的文件可以帮助找出问题的根本原因。这有助于快速定位错误&#x…

深入解析 curl:掌握命令行的网络传输利器

当我们使用 curl 进行网络请求时&#xff0c;了解如何有效地使用参数是非常重要的。curl 提供了许多参数&#xff0c;用于控制请求的行为和配置。在这篇博客文章中&#xff0c;我们将详细解释一些常用的 curl 参数&#xff0c;帮助你更好地理解如何利用这个强大的工具。 什么是…

兵者多诡(HCTF2016)

环境:https://github.com/MartinxMax/CTFer_Zero_one 题目简介 解题过程 登录首页 提交png图片上传抓包&#xff0c;可以看到是向upload文件提交数据 在fp参数中尝试伪协议读取home.php文件 http://127.0.0.1:88/HCTF2016-LFI/home.php?fpphp://filter/readconvert.base64…

将YOLO数据集按照指定比例划分(训练集、验证集、测试集)的详细教程

1.将训练集、验证集、测试集按照7:2:1随机划分 1.项目准备 1.在项目下新建一个py文件&#xff0c;名字就叫做splitDataset1.py 2.将自己需要划分的原数据集就放在项目文件夹下面 以我的为例&#xff0c;我的原数据集名字叫做hatDataXml 里面的JPEGImages装的是图片 Annota…

【物联网】磁介质存储设备——机械硬盘

磁介质存储设备是一种使用磁性材料作为存储介质的设备&#xff0c;用于存储和读取数据。常见的磁介质存储设备包括硬盘驱动器&#xff08;HDD&#xff09;、软盘驱动器和磁带。 文章目录 一、机械硬盘存储器的基本结构与分类1.1 基本结构1.2 分类 二、硬盘的信息分布三、机械硬…

计算机网络的故事——HTTP报文内的HTTP信息

HTTP报文内的HTTP信息 文章目录 HTTP报文内的HTTP信息一、HTTP 报文二、请求报文及响应报文的结构三、编码提升传输速率 一、HTTP 报文 HTTP报文是由多行&#xff08;CRLF作换行符&#xff09;数据构成的字符串文本&#xff0c;HTTP报文可以分为报文首部和报文主体两部分&…

Android ChatCPT集成

准备工作 ChatGPT账号(openai) 集成好网络框架(默认使用Retrofit) 接入 选择modele 这里使用的是 「https://api.openai.com/v1/chat/completions」 创建API Keys 运行效果 POST https://api.openai.com/v1/chat/completions Content-Type: application/json Content-Length:…

RHCA之路---EX280(8)

RHCA之路—EX280(8) 1. 题目 On master.lab.example.com using the template file in http://materials.example.com/exam280/gogs as a basis, install an application in the ditto project according to the following requirements: All of the registry entries must poi…

AndroidTV端:酒店扫码认证投屏DLNA

被老板叼了几次了&#xff0c;最近实在忍不了&#xff0c;准备离职&#xff1b; 但是担心离职后长时间没有办法找到工作 就想贡献一套平时琢磨出来的程序&#xff0c;请各位有能力的话带我熬过这凛冽的寒冬。 目前写出来的&#xff0c;有三个端&#xff1a;安卓TV端&#xf…

Kali之BurpSuite_pro安装配置

文章目录 配置jdk环境安装BurpSuitePro设置快捷方式启动方式 BurpSuite2021专业版本地址&#xff1a; 下载链接&#xff1a;https://pan.baidu.com/s/1PjzcukRDoc_ZFjrNxI8UjA 提取码&#xff1a;nwm7 我的安装工具都在/home/kali/tools/ 解压后我放在burpsuite_pro目录下 把j…

Harbor 私人(企业)docker镜像仓库部署

目录 一、资源下载二、配置前准备三、配置harbor.yml文件四、安装五、上传镜像到Harbor docker镜像仓库 一、资源下载 在GitHub上可以找到相关的下载&#xff1a;https://github.com/goharbor/harbor/releases 或者Linux直接wget&#xff1a; ┌──(root㉿kali)-[~] └─# w…

飞行动力学 - 第17节-航向静稳定性 之 基础点摘要

飞行动力学 - 第17节-航向静稳定性 之 基础点摘要 1. 航向静稳定性2. 航向静稳定性的组成3. 参考资料 1. 航向静稳定性 飞机受到侧滑扰动后&#xff0c;如果能产生使机头指向原来方向的力矩&#xff0c;抵消侧滑&#xff0c;则称为航向静稳定性。 2. 航向静稳定性的组成 飞机…

vue3+ts+vite项目引入echarts

概述 技术栈&#xff1a;Vue3 Ts Vite Echarts 简介&#xff1a; 图文详解&#xff0c;教你如何在Vue3项目中引入Echarts&#xff0c;封装Echarts组件&#xff0c;并实现常用Echarts图例 文章目录 概述一、先看效果1.1 静态效果1.2 动态效果 二、话不多数&#xff0c;引入 …

三步搭建个人网站并发布上线【内网穿透】

三步搭建个人网站并发布上线【内网穿透】 文章目录 三步搭建个人网站并发布上线【内网穿透】前言一、在本地电脑上制作一个网站二、使用WordPress建立网站三、通过cpolar建立的数据隧道发布到公网上 前言 在这个个性飞扬的时代&#xff0c;每个人都希望拥有表现自我的平台&…

C++(QT)画图行车

通过鼠标在窗口上点击形成多个点的连线&#xff0c;绘制一辆汽车沿着绘制的连线轨迹前进。要求连线点数大于20.可以通过清除按钮清除已经绘制的连线&#xff0c;并可以重新绘制一条轨迹连线。当车辆行驶到轨迹终点时&#xff0c;自动停止。&#xff08;汽车实在可用方块代替&am…