【设计模式深度剖析】【1】【结构型】【代理模式】| 玩游戏打怪、升级为例加深理解

news/2024/7/22 13:39:03/文章来源:https://blog.csdn.net/qq_28727015/article/details/139077802

👈️上一篇:创建型设计模式对比    |   下一篇:装饰器模式👉️

目 录

  • 代理模式
  • 定义
    • 英文原话
    • 直译
    • 如何理解?
  • 3个角色
    • UML类图
    • 1. 抽象主题(Subject)角色
    • 2. 代理类:代理主题(Proxy Subject)角色
    • 3. 被代理类:真实主题(Real Subject)角色
    • 代码示例
      • 1. 真实主题,被代理类
      • 2. 抽象主题
      • 3. 代理类
      • 4. 测试类
  • 代理模式的种类
  • 代理模式的优点
  • 示例解析:玩游戏打怪、升级示例
    • UML类图
    • 1. 真实主题RealSubject:GamePlayer实现IGamePlayer接口中的方法
    • 抽象主题Subject:IGamePlayer接口对游戏玩家进行抽象
    • 代理主题ProxySubject:GamePlayerProxy是代理类
    • 测试类

代理模式

定义

英文原话

Provide a surrogate or placeholder for another object to control access to it.

直译

为另一个对象提供代理或占位符以控制对它的访问

如何理解?

字面上不好理解的话可以结合代码进一步理解下,从具体实现上分析:

抽象主题角色,是对被代理类的抽象,被代理类就看作是对抽象主题角色类的实现,被代理类的实现就是核心功能的实现

同时,代理对象中持有被代理对象的引用,

代理类也实现了被代理类相同的接口,

这样,通过代理类可以增强被代理类的逻辑,

在被代理对象的逻辑前后可以增加一些逻辑,比如获取请求参数,添加日志等,这些非核心的逻辑,可以在代理类中进行增强。

代理模式应用非常广泛,大到一个系统框架、企业平台,小到事务处理、代码片段,随处可见代理模式的使用,例如,Java RMI的远程调用就是一种代理模式的应用,AOP也可以通过代理模式实现。

3个角色

UML类图

proxy.png

1. 抽象主题(Subject)角色

该角色是真实主题和代理主题的共同接口,以便在任何可以使用真实主题的地方都可以使用代理主题。

2. 代理类:代理主题(Proxy Subject)角色

也叫做委托类、代理类,该角色负责控制对真实主题的引用,负责在需要的时候创建或删除真实主题对象,并且在真实主题角色处理完毕前后做预处理和善后处理工作。

3. 被代理类:真实主题(Real Subject)角色

该角色也叫做被委托角色、被代理角色,是业务逻辑的具体执行者。

代码示例

1. 真实主题,被代理类

package com.polaris.designpattern.list2.structural.pattern1.proxy.proto;public class Target implements AbstractSubject {@Overridepublic void m1() {System.out.println("target implements. Core business logic");}
}

2. 抽象主题

抽取核心业务逻辑接口方法m1()出来,该方法源自被代理对象,因此被代理类的m1()方法就可以看作是对它的实现,被代理类添加 implements AbstractSubject表示对抽象主题的实现;

package com.polaris.designpattern.list2.structural.pattern1.proxy.proto;public interface AbstractSubject {void m1();
}

3. 代理类

代理被代理的类,对被代理类的逻辑(抽象主题进行了抽象)进行增强,

前提是代理类实现了抽象主题的抽象方法,同时持有被代理类的对象(可通过构造函数传入)

注意这里的构造函数传入的是Target实例,更通用的可以使用抽象主题角色AbstractSubject类型;

package com.polaris.designpattern.list2.structural.pattern1.proxy.proto;public class Proxy implements AbstractSubject {private Target target;public Proxy(Target target) {this.target = target;}@Overridepublic void m1() {before();target.m1();after();}private void before() {System.out.println("enhanced logic: before...");}private void after() {System.out.println("enhanced logic: after...");}
}

4. 测试类

package com.polaris.designpattern.list2.structural.pattern1.proxy.proto;public class DemoTest {public static void main(String[] args) {Target target = new Target();Proxy proxy = new Proxy(target);proxy.m1();}
}/* Output:
enhanced logic: before...
target implements. Core business logic
enhanced logic: after...
*///~

代理模式的种类

简单了解一下:

  1. 远程(Remote)代理:为一个位于不同的地址空间的对象提供一个局部代表对象。这个不同的地址空间可以是在本机器中,也可以在另一台机器中。
  2. 虚拟(Virtual**)**代理:有时需要创建一些消耗较多资源的对象,可以首先创建代理对象,而将真实对象的创建延迟。例如,加载一个很大的图片,可以通过图片的代理来代替真正的图片。
  3. 保护(Protect or Access)代理:控制对一个对象的访问,如果需要,可以给不同的用户提供不同级别的使用权限。
  4. 缓存(Cache)代理:为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。
  5. 同步(Synchronization)代理:使几个用户能够同时使用一个对象而没有冲突。
  6. 智能引用(Smart Reference)代理:当一个对象被引用时,提供一些额外的操作,例如,记录访问的流量和次数等。

代理模式的优点

  1. 职责清晰真实的角色实现实际的业务逻辑,不用关心其他非本职的事务,通过后期的代理完成附加的事务,附带的结果就是编程简洁清晰。
  2. 高扩展性:具体主题角色随需求不同可能有很多种,但只要实现了接口,代理类完全可以不做任何修改的情况下代理各种真实主题角色
  3. 智能化:代理类可以在运行时才确定需要去代理的真实主题,这是一种强大的功能。

示例解析:玩游戏打怪、升级示例

UML类图

gamerproxy.png

  • 主题类和代理类同时实现接口
  • 主题类,就是被代理类,完成主要业务逻辑
  • 附加业务在代理类中完成
  • 客户端调用:
    • 声明接口的两个示例分别指向主题类与代理类的实例对象;
    • 其中,在代理类示例创建时传入主题类的实例(参数类型可以放大,参数定义为接口类型,当然主题类实现类此接口,属于此接口类型,可以被传入)。

1. 真实主题RealSubject:GamePlayer实现IGamePlayer接口中的方法

被代理类的具体实现,是最核心的业务逻辑,这里玩游戏最核心的就是打怪,升级;

package com.polaris.designpattern.list2.structural.pattern1.proxy;public class GamePlayer implements IGamePlayer {private String name = "";public GamePlayer(String name) {this.name = name;}@Overridepublic void killBoss() {System.out.println(this.name + "在打怪!");}@Overridepublic void upGrade() {System.out.println(this.name + "成功升了1级!");}
}

抽象主题Subject:IGamePlayer接口对游戏玩家进行抽象

抽象主题,抽象出打怪升级两个核心业务逻辑,方便代理类进行实现,增强被代理类的逻辑

package com.polaris.designpattern.list2.structural.pattern1.proxy;public interface IGamePlayer {//杀怪void killBoss();//升级void upGrade();
}

代理主题ProxySubject:GamePlayerProxy是代理类

代理主题,在被代理类的核心业务逻辑实现(打怪、升级)的基础上增加非核心业务逻辑:加日志、计时,

因此代理类是对被代理类的增强、强化

他持有被代理类的引用,通过构造函数初始化

package com.polaris.designpattern.list2.structural.pattern1.proxy;import java.util.Date;public class GamePlayerProxy implements IGamePlayer {private IGamePlayer player = null;public GamePlayerProxy(IGamePlayer player) {this.player = player;}//记录打怪的时间private void log() {System.out.println("打怪时间 " + new Date().toString());}@Overridepublic void killBoss() {this.log();player.killBoss();}@Overridepublic void upGrade() {player.upGrade();this.countTime();}//计时private void countTime() {System.out.println("升1级耗时50小时");}}

测试类

package com.polaris.designpattern.list2.structural.pattern1.proxy;public class DemoTest {public static void main(String[] args) {IGamePlayer player = new GamePlayer("李逍遥");IGamePlayer proxy = new GamePlayerProxy(player);proxy.killBoss();proxy.upGrade();}
}/* Output:
打怪时间 Mon May 20 23:35:58 CST 2024
李逍遥在打怪!
李逍遥成功升了1级!
升1级耗时50小时
*///~

👈️上一篇:创建型设计模式对比    |   下一篇:装饰器模式👉️

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【图神经网络——GATv2】

图神经网络——GATV2 GATV2GATV2代码实现:GATV2在MUTAG数据集上的应用:任务:推断分子是否抑制HIV病毒复制 GATV2 GATV2 ? 什么是GATV2呢? 相比较于GAT 有什么区别呢? GAT:使用的是固定的注意力机…

将本地项目上传到 gitee 仓库

1、创建 gitee 仓库 到 gitee 官网,新建仓库 配置新建仓库 完成仓库的创建 项目上传到仓库 上传项目需要安装git git官方下载地址:git下载地址 安装完成,前往本地项目所在文件夹,右击选择 Git Bash Here 刚下载完成需要配置G…

java面试(多线程)

线程和进程的区别 程序由指令和数据组成,但这些指令要运行,数据要读写,就必须将指令加载至CPU,数据加载至内存。在指令运行过程中还需要用到磁盘,网络等设备。进程就是用来加载指令,管理内存,管…

vue3主题切换按钮与功能实现

代码: <template><div class"slideThree"><label class"theme-switch"><inputtype"checkbox"class"checkbox"v-model"isChecked"change"setTheme"id"slideThree"name"check…

埃文科技携数据要素产品亮相第七届数字中国建设峰会

第七届数字中国建设峰会&#xff08;以下简称“峰会”&#xff09;于2024年5月24日至25日在福建省福州市举办。此次峰会是国家数据工作体系优化调整后举办的首次数字中国建设峰会。本届峰会由国家发展改革委、国家数据局、国家网信办、科技部、国务院国资委、福建省人民政府共同…

【MATLAB】基于VMD-SSA-GRU的回归预测模型

有意向获取代码&#xff0c;请转文末观看代码获取方式~ 1 基本定义 基于VMD-SSA-GRU的回归预测模型是一种集成了变分模态分解&#xff08;VMD&#xff09;、同步滑动平均&#xff08;SSA&#xff09;和门控循环单元&#xff08;GRU&#xff09;的复杂时间序列预测方法。下面将…

leetcode 530.二叉搜索树的最小绝对差 、501.二叉搜索树中的众数 、236. 二叉树的最近公共祖先

leetcode 530.二叉搜索树的最小绝对差 、501.二叉搜索树中的众数 、236. 二叉树的最近公共祖先 leetcode 530.二叉搜索树的最小绝对差 题目链接&#xff1a;https://leetcode.cn/problems/maximum-binary-tree/description/ 题目&#xff1a; 给你一个二叉搜索树的根节点 r…

BUUCTF-misc刷题

被嗅探的流量1 用wireshark打开附件&#xff0c;Ctrlf&#xff0c;然后搜索flag&#xff0c;我们在这么多数据包中搜索带有flag字符的 然后第一个包中上传了一个名叫flag的.jpg文件 然后直接ctrlf&#xff0c;搜索flag{ 得到flag&#xff1a;flag{da73d88936010da1eeeb36e945e…

php 连接sqlserver步骤

1.首先要确定使用的是sqlserver的哪个版本&#xff0c;比如sqlserver2012 2.确定服务器是64位还是32位的 3.确认一下使用php的哪个版本&#xff0c;比如php7.1 SQL Server 的 Microsoft PHP 驱动程序 Microsoft Drivers for PHP 支持矩阵 - PHP drivers for SQL Server | Mi…

香橙派Kunpeng Pro深度测评:开发者的新选择

文章目录 前言&#xff1a;一、开发板外观与介绍1.接口介绍2.按键以及LED的介绍 二、开发板上电以及系统启动三、更新安装相关命令四、查看相关配置五、vim个性化配置六、开发板网络测试1.网口测试&#xff1a;2.WiFi模块测试&#xff1a; 七、扩展引脚功能测试1.TFTP传输文件2…

C++---运算符重载

运算符重载介绍 在类中重新定义运算符&#xff0c;赋予运算符新的功能以适应类的运算&#xff0c;就称为运算符重载。 运算符重载是一种形式的C多态,它使得对象操作更直观,本质上也是属于函数重载。 实际上&#xff0c;我们已经在不知不觉之中使用了运算符重载。例如&#xff…

spark的简单学习一

一 RDD 1.1 RDD的概述 1.RDD&#xff08;Resilient Distributed Dataset&#xff0c;弹性分布式数据集&#xff09;是Apache Spark中的一个核心概念。它是Spark中用于表示不可变、可分区、里面的元素可并行计算的集合。RDD提供了一种高度受限的共享内存模型&#xff0c;即RD…

如何基于springboot构建cas最新版源码?

环境准备 下载JDK21 https://download.oracle.com/java/21/archive/jdk-21.0.2_windows-x64_bin.zip下载gradle 8.5并配置环境变量 https://gradle.org/next-steps/?version8.5&formatbin下载项目git clone http://gitlab.ruishan.cc/meta/anka-authentication.git 开始…

【CSP CCF记录】201909-1 小明种苹果

题目 过程 #include<bits/stdc.h> using namespace std; int N,M; long long tree[1010]; int main() {cin>>N>>M;long long result0,max0;//result剩余苹果&#xff0c;max最大疏果个数 int id0;//id最大疏果的果树编号 for(int i1;i<N;i){long long b0…

【LeetCode】【9】回文数(1047字)

文章目录 [toc]题目描述样例输入输出与解释样例1样例2样例3 提示进阶Python实现 个人主页&#xff1a;丷从心 系列专栏&#xff1a;LeetCode 刷题指南&#xff1a;LeetCode刷题指南 题目描述 给一个整数x&#xff0c;如果x是一个回文整数&#xff0c;返回true&#xff1b;否…

Java数组的使用

Java数组的使用 前言一、数组基本用法什么是数组注意事项创建数组基本语法代码示例注意事项 数组的使用代码示例获取长度 & 访问元素注意事项 下标越界遍历数组编程求平均成绩Mathrandom类现有100个学生&#xff0c;编程求平均成绩 使用 for-each 遍历数组 二、数组作为方法…

解线性方程组——最速下降法及图形化表示 | 北太天元 or matlab

一、思路转变 A为对称正定矩阵&#xff0c; A x b Ax b Axb 求解向量 x x x这个问题可以转化为一个求 f ( x ) f(x) f(x)极小值点的问题&#xff0c;为什么可以这样&#xff1a; f ( x ) 1 2 x T A x − x T b c f(x) \frac{1}{2}x^TAx - x^Tb c f(x)21​xTAx−xTbc 可…

tty/pty/console/getty/shell/telnet

tty 终端(termimal)= tty(Teletypewriter, 电传打印机),作用是提供一个命令的输入输出环境,在linux下使用组合键ctrl+alt+T打开的就是终端,可以认为terminal和tty是同义词。 tty泛指所有的终端设置,这些是真实存在的设备。 通过tty命令可以查看当前终端连接的设备。…

Linux 一键部署alfresco 6

alfresco 前言 Alfresco是一个流行的企业级开源内容管理系统和协作平台。它提供了丰富的功能,包括文档管理、记录管理、协作工具、工作流管理、搜索和版本控制等。Alfresco还具有灵活的部署选项,可以作为本地部署的软件或云服务来使用。 该平台可以帮助组织管理和存储各种类…

WPS文件没有保存怎么恢复?5个解决方案轻松恢复!

“我在WPS上编辑了一个文件&#xff0c;但是还没来得及将它保存&#xff0c;我不小心就退出软件了&#xff0c;现在不知道有什么方法可以恢复WPS文件呢&#xff1f;大家可以帮帮我吗” WPS作为一款功能强大且用户友好的软件&#xff0c;给我们的工作带来了很多的便利。但我们在…