关键词:
从王者荣耀看设计模式(虚拟代理模式)
一.简介
王者荣耀游戏设置了很多种游戏模式,比如:王者模拟战、无限乱斗、梦境大乱斗、火焰山大战等。当从王者荣耀的主界面进入各类模式的界面时,由于网络原因,会存在一定程度的延时(会有一个圈圈在主界面一直转啊转啊转(??へ??╬)),直到加载完图片,会跳转到各模式界面。
二.虚拟代理(作为创建开销大的对象的代表)
虚拟代理是作为创建开销大的对象的代表。虚拟代理经常直到我们真正需要一个对象的时候才创建它。当对象在创建前和创建中时,由虚拟代理来扮演对象的替身。对象创建后,代理就会将请求直接委托给对象。
三.结构图
四.设计类图
五.顺序图
六.ImageProxy如何工作
⑴. 我们创建一个用来显示的ImageProxy代理,paintIcon()方法会被调用,而ImageProxy会产生线程取得图像,并创建ImageIcon.
⑵. 在某个时间点,也就是图片下载完成后,图像被返回,ImageIcon被完整实例化。
⑶. 在ImageIcon被创建后,下次调用paintIcon时,代理就委托ImageIcon进行。
七.代码实现
编写ImageProxy代码
package com.practice.VirtualProxy;
import java.awt.Component;
import java.awt.Graphics;
import java.net.URL;
import javax.swing.Icon;
import javax.swing.ImageIcon;
//实现Icon接口
public class ImageProxy implements Icon
ImageIcon imageIcon;
URL imageURL;
Thread retrievalThread;
boolean retrieving = false;
// 将图片的URL传入构造器中
public ImageProxy(URL url)
imageURL = url;
// 在图像加载完毕前,返回默认的宽和高
// 图像加载完毕后,装给iamgeIcon处理
public int getIconWidth()
if (imageIcon != null)
return imageIcon.getIconWidth();
else
return 800;
public int getIconHeight()
if (imageIcon != null)
return imageIcon.getIconHeight();
else
return 600;
// 当要在屏幕上绘制图像时,就调用此方法
public void paintIcon(final Component c, Graphics g, int x, int y)
// 如果已经有了icon,就画出
if (imageIcon != null)
imageIcon.paintIcon(c, g, x, y);
else
// 还没有icon时,就显示“加载中...”的消息
g.drawString("游戏界面加载中,请稍后...", x + 300, y + 190);
if (!retrieving)
retrieving = true;
// 在这个线程中加载真正的icon图像。注意,加载图像和ImageIcon是同步(synchronous)
// 也就是说,只有在加载完之后,ImageIcon构造器才会返回。这样,我们的程序会耗在这里
// 所以要把加载变成异步(asynchronous)的。
retrievalThread = new Thread(new Runnable()
public void run()
try
imageIcon = new ImageIcon(imageURL, "GamePage");
c.repaint();
catch (Exception e)
e.printStackTrace();
);
retrievalThread.start();
编写ImageComponent(用来放到frame布局中用来显示图片)
package com.practice.VirtualProxy;
import java.awt.*;
import javax.swing.*;
class ImageComponent extends JComponent
private static final long serialVersionUID = 1L;
private Icon icon;
public ImageComponent(Icon icon)
this.icon = icon;
public void setIcon(Icon icon)
this.icon = icon;
public void paintComponent(Graphics g)
super.paintComponent(g);
int w = icon.getIconWidth();
int h = icon.getIconHeight();
int x = (800 - w)/2;
int y = (600 - h)/2;
icon.paintIcon(this, g, x, y);
测试代码ImageProxyTestDrive
package com.practice.VirtualProxy;
import java.net.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
public class ImageProxyTestDrive
ImageComponent imageComponent;
JFrame frame = new JFrame("王者荣耀页面加载器");
JMenuBar menuBar; // 菜单栏
JMenu menu; // 菜单
Hashtable<String, String> cds = new Hashtable<String, String>();
public static void main (String[] args) throws Exception
new ImageProxyTestDrive();
public ImageProxyTestDrive() throws Exception
// 构造菜单项用的, key=CD名, value=URL
cds.put("王者首页", "https://graph.baidu.com/resource/126029c103ffff3795c2c01577338115.jpg");
cds.put("王者模拟战","https://graph.baidu.com/resource/126cb98ad7a209b65c44701577338030.jpg");
cds.put("无限乱斗","https://graph.baidu.com/resource/12611c1da836e79b2398701577338223.jpg");
cds.put("梦境大作战","https://graph.baidu.com/resource/126a905124f61eaabb7ff01577338291.jpg");
cds.put("火焰山大作战","https://graph.baidu.com/resource/12694ce534e244577a20b01577338346.jpg");
cds.put("克隆大作战","https://graph.baidu.com/resource/12682b0f434812cf5613a01577338523.jpg");
cds.put("契约之战","https://graph.baidu.com/resource/126e137611a3bc598acc701577338585.jpg");
// 设置初始的CD封面
//URL initialURL = new URL((String)cds.get("Once<曾经>"));
URL initialURL = new URL((String)cds.get("王者首页"));
// 建立菜单栏
menuBar = new JMenuBar();
menu = new JMenu("王者荣耀界面");
menuBar.add(menu);
frame.setJMenuBar(menuBar);
for(Enumeration<String> e = cds.keys(); e.hasMoreElements();)
String name = (String)e.nextElement();
JMenuItem menuItem = new JMenuItem(name);
menu.add(menuItem);
menuItem.addActionListener(new ActionListener()
public void actionPerformed(ActionEvent event)
imageComponent.setIcon(new ImageProxy(getPicUrl(event.getActionCommand())));
frame.repaint();
);
// set up frame and menus
Icon icon = new ImageProxy(initialURL);
imageComponent = new ImageComponent(icon);
frame.getContentPane().add(imageComponent);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800,600);
frame.setVisible(true);
URL getPicUrl(String name)
try
return new URL((String)cds.get(name));
catch (MalformedURLException e)
e.printStackTrace();
return null;
八.源代码下载
从王者荣耀看设计模式(十七.原型模式)(代码片段)
从王者荣耀看设计模式(原型模式)一.简介王者荣耀包含有很多的玩法,其中有一种游戏模式只在周六和周日开放,那就是——克隆模式。与常规的游戏双方阵营只允许出现单一英雄不同,在克隆模式中,双方各选择一个英雄进行... 查看详情
从王者荣耀看设计模式(二十一.解释器模式)(代码片段)
从王者荣耀看设计模式(解释器模式)一.简介为了方便玩家沟通,王者荣耀允许玩家在游戏的同时录入语音,然后系统自动解释录入的语音,转换为字符串显示在玩家聊天的区域─━_─━?二.模式动机在某些情况下,为了更好... 查看详情
从王者荣耀看设计模式(十六.建造者模式)(代码片段)
从王者荣耀看设计模式(建造者模式)一.简介为了玩王者荣耀的游戏体验感,不少玩家都会选择花钱购买自己常用英雄的皮肤。一方面,购买的皮肤通常要比原画更加"炫酷"。另一方面,购买的英雄皮肤常常伴随有特殊的回... 查看详情
从王者荣耀看设计模式(二十三.访问者模式)(代码片段)
从王者荣耀看设计模式一.简介在游戏中,根据场上状况给英雄配备合适的装备是赢的比赛的重要环节。对于刚开始玩王者荣耀(低端玩家likeme),在选择装备的时候只会关注装备能给英雄带来多少伤害的增幅(装备属性),而大... 查看详情
从王者荣耀看设计模式(二十一.中介者模式)(代码片段)
从王者荣耀看设计模式(中介者模式)一.简介在王者荣耀中,有一个简单的聊天室,在聊天室中。玩家点击综合可以与全服的玩家发送消息,点击好友可向指定好友玩家私发信息。|??ω?`)二.模式动机联合国是一个协调组织,各... 查看详情
1从王者荣耀浅谈设计模式(简单工厂模式)
姓名:简单工厂模式英文名:factorymethodPattern价值观:容易扩展王者荣耀的英雄一个个阶段性的上线,有射手、坦克、刺客等等,每个英雄的类型,技能,级别都不一样,这里主要举个例子说明英雄扩展代码:英雄接口:英雄的... 查看详情
从王者荣耀谈设计模式?
软件开发中涉及到的设计模式很多,这里重点讨论工作中常见的一些设计模式,围绕王者荣耀中的场景进行展开。 1:策略模式策略模式demo<?php//1:抽象策略接口:王者荣耀abstractclasskingGlory abstractfunctionshowT... 查看详情
手写源码-设计模式19-备忘录模式-如果王者荣耀中有月光宝盒(代码片段)
1:主题拆解①基本介绍②如果王者荣耀中有月光宝盒③备忘录模式的优缺点④适用场景⑤应用实例⑥总结2:基本介绍 备忘录模式:在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象... 查看详情
责任链模式在王者荣耀中的应用,妙啊。(代码片段)
来源:https://blog.csdn.net/IT_charge一、简述在王者荣耀商城中,玩家可以参与夺宝抽奖。夺宝抽奖分两种,一种是积分抽奖,另一种是钻石抽奖;在平常,两种夺宝抽奖方式均可以通过60钻石/积分抽奖一次ÿ... 查看详情
javascipt设计模式初探-代理模式虚拟代理(代码片段)
文章目录前言一、举例_图片懒加载二、虚拟代理在示例中的体现总结前言虚拟代理是代理模式在性能方面的分支,个人认为有点像人工异步操作.把累活和细活从真实对象拆出来丢给代理对象,“你做完之后叫我一声,我来拿结果.”... 查看详情
转从王者荣耀看测试工作
初识测试作为一个想从事测试工作的新人,要先了解这个行业的背景,职位发展,干啥事情。。。选择很重要,作出选择之前要充分了解,这也是对自己负责。测试基本功底对于测试而言,基本的用例设计,测试流程,基础的代... 查看详情
设计模式从青铜到王者第五篇:创建型模式之简单工厂模式(simplefactorypattern)(代码片段)
系列文章目录文章目录系列文章目录前言一、简单工厂模式模式动机二、简单工厂模式模式定义三、简单工厂模式模式结构四、简单工厂模式时序图五、简单工厂模式代码分析六、简单工厂模式模式分析七、简单工厂模式优点八... 查看详情
unity实战之王者荣耀段位计算(代码片段)
...,但是既然有这个机会,我还是愿意尝试一下。正巧最近王者的段位也到达了一个高度,给大家炫一下~~段位描述这不,一来就涉及到了段位。段位分为大段位和小段位。大段位从低到高分别是:青铜,白银,黄金,铂金,钻石... 查看详情
代理模式(代码片段)
...态代理。 两种代理从虚拟机加载类的角度来讲,本质上都是一样的,都是在原有类的行为基础上,加入一些多出的行为,甚至完全替换原有的行为。 静态代... 查看详情
设计模式从青铜到王者第八篇:创建型模式之建造者模式(builderpattern)(代码片段)
系列文章目录文章目录系列文章目录前言建一栋房子总共分几步?建造者模式告诉你答案!1.建造者模式简介2.建造者模式结构3.建造者模式代码实例3.1.定义产品类House3.2.定义建造者3.2.1.定义抽象建造者AbstractBuilder3.2.2.定... 查看详情
零代码以“王者荣耀”为例解析设计七原则
摘要:一文助你深入理解设计模式七大原则。本文分享自华为云社区《零代码以“王者荣耀”为例解析设计七原则,助你面试拿“五杀”》,作者:陈言必行。前言:所有举例都是王者荣耀相关内容(不玩王者... 查看详情
设计模式从青铜到王者第七篇:创建型模式之抽象工厂模式(abstractfactory)(代码片段)
...优点:缺点:适用环境:总结前言回顾之前的设计模式,简单工厂模式所有逻辑都封装在工厂类中ÿ 查看详情
设计模式代理模式(动态代理|模拟java虚拟机生成对应的代理对象类)(代码片段)
文章目录前言一、模拟JVM生成对应的代理对象二、模拟JVM生成对应的代理对象完整流程展示1、目标对象接口2、被代理对象3、调用处理程序4、模拟JVM生成的代理对象类5、客户端前言动态代理使用流程:①创建目标对象:创建目标... 查看详情