java设计模式之代理设计模式(Spring核心思想AOP的底层设计模式)

结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。

由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。

结构型模式分为以下 7 种:

  • 代理模式

  • 适配器模式

  • 装饰者模式

  • 桥接模式

  • 外观模式

  • 组合模式

  • 享元模式

二、现有开发中存在的问题

===============================================================================

  • 问题:在JavaEE分层开发开发中,那个层次对于我们来讲最重要?

DAO —> Service --> Controller

JavaEE分层开发中,最为重要的是Service层

1、定义业务层接口

public interface EmpService {

/**

  • 分页

  • @return 当前页的员工

*/

public List selectEmpByPage(int pageNumber);

/**

  • 总的页数

  • @return 数据库有多少条员工数据

*/

public int selectTotalPage();

/**

  • 添加员工

  • @param emp

*/

public void addEmp(Emp emp);

/**

  • 根据id删除员工

  • @param id

*/

public void dropEmp(Integer id);

/**

  • 根据id修改员工信息

  • @param emp

*/

public void update(Emp emp);

/**

  • 批量删除员工

  • @param ids

*/

public void plDeleteEmp(List ids);

/**

  • 更具id查询员工,用于数据回显

  • @param id

  • @return

*/

public Emp queryEmp(Integer id);

}

2、实现业务接口

public class EmpServiceImpl implements EmpService {

@Override

public List selectEmpByPage(int pageNumber) {

EmpDao mapper = (EmpDao) MybatisUtil.getMapper(EmpDao.class);

//设置每页展示的页数

int rows = 3;

//设置第几页开始的起始条数

int begin = (pageNumber - 1) * rows;

List emps = mapper.selectEmpByPage(begin, rows);

MybatisUtil.close();

return emps;

}

@Override

public int selectTotalPage() {

EmpDao mapper = (EmpDao) MybatisUtil.getMapper(EmpDao.class);

int i = mapper.selectTotalCount();

int rows = 3;

int page = 0;

if (i % rows == 0) {

page = i / rows;

} else {

page = i / rows + 1;

}

MybatisUtil.close();

return page;

}

@Override

public void addEmp(Emp emp) {

EmpDao mapper = (EmpDao) MybatisUtil.getMapper(EmpDao.class);

mapper.insertEmp(emp);

MybatisUtil.commit();

}

@Override

public void dropEmp(Integer id) {

EmpDao mapper = (EmpDao) MybatisUtil.getMapper(EmpDao.class);

mapper.deleteEmp(id);

MybatisUtil.commit();

}

@Override

public void update(Emp emp) {

EmpDao mapper = (EmpDao) MybatisUtil.getMapper(EmpDao.class);

mapper.update(emp);

MybatisUtil.commit();

}

@Override

public void plDeleteEmp(List ids) {

EmpDao mapper = (EmpDao) MybatisUtil.getMapper(EmpDao.class);

mapper.plDeleteEmp(ids);

MybatisUtil.commit();

}

@Override

public Emp queryEmp(Integer id) {

EmpDao mapper = (EmpDao) MybatisUtil.getMapper(EmpDao.class);

Emp emp = mapper.queryEmp(id);

MybatisUtil.close();

return emp;

}

}

3、Service层中包含了哪些代码?

Service层中 = 核心功能(几十行 上百代码) + 额外功能(附加功能)

  1. 核心功能

业务运算

DAO调用

  1. 额外功能

  2. 不属于业务

  3. 可有可无

  4. 代码量很小

事务、日志、性能…

从下图中可以看出,现有业务层中控制事务代码出现了大量的冗余,如何解决现有业务层出现的冗余问题?

4、额外功能书写在Service层中好不好?

Service层的调用者的角度(Controller):需要在Service层书写额外功能。

软件设计者:Service层不需要额外功能

5、现实生活中的解决方式

  1. 住酒店不一定需要亲自到酒店去,还可以通过微信支付下的同程艺龙来订酒店。

  2. 我们可以通过中介去找房子,不用直接跟房东沟通(现实生活中,我们更希望直接跟房东沟通)

  3. 春运买票买不到,我们可以找黄牛替我们抢票

  4. 想访问国外的网站,可以使用代理服务器进行访问。

三、代理设计模式

===========================================================================

单词 proxy [ˈprɑːksi] 代理

1、概述

由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。

Java中的代理按照代理类生成时机不同 又分为静态代理和动态代理。

  1. "静态代理"代理类在编译期就生成

  2. "动态代理"代理类则是在Java运行时动态生成。动态代理又有JDK代理和CGLib代理两种。

2、结构

代理(Proxy)模式分为三种角色:

  • 抽象主题(Subject)类: 通过接口或抽象类 声明真实主题和代理对象实现的业务方法。

  • 真实主题(Real Subject)类: 实现了抽象主题中的具体业务,是代理对象所代表的真实对象,是最终要引用的对象。

  • 代理(Proxy)类 : 提供了与真实主题相同的接口,其内部含有对真实主题的引用,它可以访问、控制或扩展真实主题的功能。

联想,戴尔就是真实主题(Subject),代理对象(地方代理商),真实主题类(联想公司对象),代理类(地方代理商)代理联想和戴尔,代理的规范就是抽象主题类

1、什么是代理? 中介

代理是java中的一种设计模式:代理设计模式

2、为什么需要代理?

有没有代理都可以完成当前的功能,但是存在代理之后,更加专注于核心的业务功能,额外功能可以交给代理去做,实现功能的解耦合

  • 生活案例:小红正在做饭,但是男朋友小李给他发消息,他如果边做饭边发消息,影响做饭的效率,他就可以口述给她的闺蜜让她闺蜜和男朋友聊天,自己认真做饭,闺蜜就是代理,"如花"就是一个接口

在这里插入图片描述

3、代理的好处?

保证核心功能完成的前提下,同时兼顾额外功能

4、怎么开发代理对象?

1、代理对象一定依赖于核心业务对象

2、代理对象和核心业务对象一定要实现相同的接口

四、静态代理

=========================================================================

1、什么是静态代理

  • 静态代理:手工为某个类开发一个代理类,一个类对应一个代理类

  • 通过代理类,为原始类(目标)增加额外的功能

  • 好处:利于原始类(目标)的维护

2、名词解释

  1. 目标类 原始类 被代理的对象

指的是 业务类 (核心功能 --> 业务运算 DAO调用)

  1. 目标方法,原始方法

目标类(原始类)中的方法 就是目标方法(原始方法)

  1. 额外功能 (附加功能)

日志,事务,性能,数据清洗

3、代理开发的核心要素

代理类 = 目标类(原始类) + 额外功能 + 原始类(目标类)实现相同的接口

房东 —> public interface UserService{

m1

m2

}

UserServiceImpl implements UserService{

m1 —> 业务运算 DAO调用

m2

}

UserServiceProxy implements UserService

m1

m2

4、编码(静态代理的开发)

  • 开发代理的原则: 代理类和目标类功能一致且实现相同的接口,同时代理类中依赖于目标类对象
(1)UserService接口

public interface UserService {

void save(String name);

void delete(String id);

void update();

String findAll(String name);

String findOne(String id);

}

(2)开发静态代理类

/**

  • @author 王恒杰

  • @version 1.0

  • @date 2021/11/11 11:14

  • @email 1078993387@qq.com

  • @Address 天津

  • @Description:开发原则:代理类和目标类实现相同接口,依赖于真正的目标类

*/

public class UserServiceStaticProxy implements UserService{

/**

  • 真正的目标类 (target 原始业务逻辑对象)

*/

private UserService userService;

public void setUserService(UserService userService) {

this.userService = userService;

}

@Override

public void save(String name) {

try {

System.out.println(“开启事务”);

userService.save(name);

System.out.println(“提交事务”);

}catch (Exception e){

System.out.println(“回滚事务”);

e.printStackTrace();

}

}

@Override

public void delete(String id) {

try {

System.out.println(“开启事务”);

userService.delete(id);

System.out.println(“提交事务”);

}catch (Exception e){

System.out.println(“回滚事务”);

e.printStackTrace();

}

}

@Override

public void update() {

try {

System.out.println(“开启事务”);

userService.update();

System.out.println(“提交事务”);

}catch (Exception e){

System.out.println(“回滚事务”);

e.printStackTrace();

}

}

@Override

public String findAll(String name) {

String all=null;

try {

System.out.println(“开启事务”);

all = userService.findAll(name);

System.out.println(“提交事务”);

}catch (Exception e){

System.out.println(“回滚事务”);

e.printStackTrace();

}

return all;

}

@Override

public String findOne(String id) {

String one=null;

try {

System.out.println(“开启事务”);

one= userService.findOne(id);

System.out.println(“提交事务”);

}catch (Exception e){

System.out.println(“回滚事务”);

e.printStackTrace();

}

return one;

}

}

(3)修改目标实现类

public class UserServiceImpl implements UserService {

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
img

面试结束复盘查漏补缺

每次面试都是检验自己知识与技术实力的一次机会,面试结束后建议大家及时总结复盘,查漏补缺,然后有针对性地进行学习,既能提高下一场面试的成功概率,还能增加自己的技术知识栈储备,可谓是一举两得。

以下最新总结的阿里P6资深Java必考题范围和答案,包含最全MySQL、Redis、Java并发编程等等面试题和答案,用于参考~

重要的事说三遍,关注+关注+关注!

历经30天,说说我的支付宝4面+美团4面+拼多多四面,侥幸全获Offer

image.png

更多笔记分享

历经30天,说说我的支付宝4面+美团4面+拼多多四面,侥幸全获Offer

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

系化!**

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-W9AZJK0x-1712192233107)]

面试结束复盘查漏补缺

每次面试都是检验自己知识与技术实力的一次机会,面试结束后建议大家及时总结复盘,查漏补缺,然后有针对性地进行学习,既能提高下一场面试的成功概率,还能增加自己的技术知识栈储备,可谓是一举两得。

以下最新总结的阿里P6资深Java必考题范围和答案,包含最全MySQL、Redis、Java并发编程等等面试题和答案,用于参考~

重要的事说三遍,关注+关注+关注!

[外链图片转存中…(img-hUX2r3jO-1712192233108)]

[外链图片转存中…(img-lzNXYWOC-1712192233108)]

更多笔记分享

[外链图片转存中…(img-T5wPE65w-1712192233109)]

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

  • 20
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值