博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【设计模式】代理模式
阅读量:4079 次
发布时间:2019-05-25

本文共 3369 字,大约阅读时间需要 11 分钟。

代理模式是一个使用率非常高的模式,其定义为:为其他对象提供一种代理以控制对这个对象的访问.

    这里举一个日常生活中我们都会碰到过的例子,比如我们在玩网游时,不想自己去重复的打怪升级,只想安安心心跟人PK娱乐,但是不升级又跟不上大众的步伐,这时怎么办呢?游戏代练这个行业就由此而生,我们可以把账号交给代练,由他们帮我们打怪升级,等升级完后,我们再拿账号玩别的.这里的游戏代练过程就相当于对于玩家玩游戏的一个代理过程,接下来我们来看类图如下:

代理模式

    接下来我们来看具体实现.

    首先新建Player类如下:

public class Player {
/** 玩家姓名 */ private String name; /** 玩家等级 */ private AtomicInteger level = new AtomicInteger(1); /** 玩家经验值 */ private AtomicInteger experience = new AtomicInteger(0); public Player(String name) { this.name = name; } /** * 刷怪,刷完一波怪获得1点经验 */ private void farm() { experience.getAndIncrement(); System.out.println(MessageFormat.format("玩家{0}刷了一波怪,当前经验为:{1}", name, experience.get())); } /** * 每获得3点经验就升1级 */ private void levelUp() { if (experience.get() % 3 == 0) { level.getAndIncrement(); System.out.println(MessageFormat.format("玩家{0}升级了,当前等级为:{1}!!!", name, level.get())); } } /** * 玩游戏(就是无尽的打怪升级-打怪升级) */ public void play() { while (true) { if (level.get() == 10) { System.out.println(MessageFormat.format("恭喜玩家{0}达到了满级10级~~~~~~~~~~~~~~~~~~~~~", name)); break; } farm(); levelUp(); } } public String getName() { return name; }}

    如上可以看到一个玩家有名字等级等,没耍三波怪可以升一级,10级满级,接下来我们看代理类PlayerProxy的实现:

public class PlayerProxy {
private ConcurrentLinkedQueue
proxyPlayers = new ConcurrentLinkedQueue<>(); /** * 有新玩家付钱来代理了,加进队列 */ private void addPlayer(String name) { proxyPlayers.offer(new Player(name)); } /** * 指定玩家开始玩游戏 */ private void play(Player player) { player.play(); } /** * 代理玩家玩游戏 */ private void proxy() { Player player = proxyPlayers.poll(); System.out.println(MessageFormat.format("代理获取的用户{0}的代理权,准备代理他玩游戏了", player.getName())); this.play(player); } /** * 批量代理玩家玩游戏 */ public void executProxy() { ExecutorService service = Executors.newCachedThreadPool(); for (int i = 0; i < 3; i++) { service.execute(() -> { while (!proxyPlayers.isEmpty()) { proxy(); } }); } }}

    可以看到,代理类中有一个队列,用于存放付钱了要代理升级的玩家们,其addPlayer方法就是玩家提供账号给他们后他们把玩家放进队列,之后开启多线程执行代理练级(一个代理当然是可以同时练多个账号的:D).

    接下来看client代码调用:

public static void main(String[] args) {    PlayerProxy playerProxy = new PlayerProxy();    for (int i = 0; i < 10; i++) {        playerProxy.addPlayer("white" + i);    }    playerProxy.executProxy();}

    我们添加了10名玩家给代理去练级,接下来看运行结果:

代理获取的用户white0的代理权,准备代理他玩游戏了代理获取的用户white1的代理权,准备代理他玩游戏了代理获取的用户white2的代理权,准备代理他玩游戏了玩家white2刷了一波怪,当前经验为:1玩家white0刷了一波怪,当前经验为:1玩家white2刷了一波怪,当前经验为:2玩家white0刷了一波怪,当前经验为:2玩家white2刷了一波怪,当前经验为:3玩家white0刷了一波怪,当前经验为:3玩家white0升级了,当前等级为:2!!!玩家white0刷了一波怪,当前经验为:4玩家white0刷了一波怪,当前经验为:5玩家white0刷了一波怪,当前经验为:6玩家white0升级了,当前等级为:3!!!玩家white2升级了,当前等级为:2!!!玩家white2刷了一波怪,当前经验为:4...................省略中间结果玩家white9刷了一波怪,当前经验为:26玩家white9刷了一波怪,当前经验为:27玩家white9升级了,当前等级为:10!!!恭喜玩家white9达到了满级10级~~~~~~~~~~~~~~~~~~~~~

    由结果看出,所有账号全部代练到满级,代理已完成任务.

代理模式优点:

  1. 职责清晰:真实角色只需关系自身业务,一些扩充事务可以交由代理类来处理比如本文客户并不用关心代理何时以何种方式代练的,不用为此写额外代码.
  2. 智能化:比如游戏代练肯定会有一些方式达到快速批量升级,比如本例代理类可以批量处理升级.读者可以扩展其他功能
  3. 扩展性:比如现在玩家需要刷5波怪升一级,此时代理类不需做任何改动,只是真实角色属性发生变化而已.

欢迎关注个人博客:blog.scarlettbai.com

你可能感兴趣的文章
关于按钮的mouseOver和rollOver
查看>>
《多线程服务器的适用场合》例释与答疑
查看>>
Netty框架
查看>>
Socket经验记录
查看>>
对RTMP视频流进行BitmapData.draw()出错的解决办法
查看>>
FMS 客户端带宽计算、带宽限制
查看>>
在线视频聊天(客服)系统开发那点事儿
查看>>
SecurityError Error 2148 SWF 不能访问本地资源
查看>>
Flex4的可视化显示对象
查看>>
Flex:自定义滚动条样式/隐藏上下箭头
查看>>
烈焰SWF解密
查看>>
Qt 静态编译后的exe太大, 可以这样压缩.
查看>>
3D游戏常用技巧Normal Mapping (法线贴图)原理解析——基础篇
查看>>
乘法逆元
查看>>
STL源码分析----神奇的 list 的 sort 算法实现
查看>>
Linux下用math.h头文件
查看>>
Linux中用st_mode判断文件类型
查看>>
Ubuntu修改host遇到unable to resolve host
查看>>
路由选择算法
查看>>
Objective-C 基础入门(一)
查看>>