《Head First 设计模式》学习笔记——代理模式
调用代理的方法,会被代理利用网络转发到远程运行,而且结果会通过网络返回给代理。再由代理将结果返回给客户。
虚拟代理常常直到我们真正须要一个对象的时候才创建它。
当对象在创建前和创建中时。由虚拟代理来扮演对象的替身。对象创建后代理就会将请求直接托付给对象。
实际的代理类是在执行时创建的,在Java中我们称这样的技术为动态代理。
利用Java的动态代理。能够实现保护代理。
import java.rmi.Remote;//用来做rmiregistry lookup的naming类在java.rmi包中
import java.rmi.RemoteException; //extends Remote这表示此接口要用来支持远程调用
public interface GumballMachineRemote extends Remote {
//准备支持的方法,每一个都要抛出RemoteException
//由于每次远程方法调用都必须考虑成“有风险的”
public int getCount() throws RemoteException;
public String getLocation() throws RemoteException; //返回值将从server经过网络运回客户。所以必须是原语类型或可序列化类型
public State getState() throws RemoteException;
} //扩展Serializable接口。使得State可序列化
public interface State extends Serializable {
public void insertQuarter();
public void ejectQuarter();
public void turnCrank();
public void dispense();
} public class HasQuarterState implements State {
private static final long serialVersionUID = 768887299984514010L;
Random randomWinner = new Random(System.currentTimeMillis()); //对于State的每一个市县。我们都在GumballMachine实例变量前面加上transientkeyword,这样就能够高考JVM不要序列化这个字段
transient GumballMachine gumballMachine; //其它方法
} //GumballMachine 要继承UnicastRemoteObject成为一个远程服务
//GumballMachine 也须要实现GumballMachineRemote这个远程接口
public class GumballMachine extends UnicastRemoteObject implements
GumballMachineRemote {
/**
*
*/
private static final long serialVersionUID = -2838970117227273571L;
State soldOutState;
State noQuarterState;
State hasQuarterState;
State soldState;
State winnerState;
State state = soldOutState;
int count = 0;
String location; //构造器须要抛出RemoteException,由于超类是这样做的
public GumballMachine(String location, int numberGumballs)
throws RemoteException {
soldOutState = new SoldOutState(this);
noQuarterState = new NoQuarterState(this);
hasQuarterState = new HasQuarterState(this);
soldState = new SoldState(this);
winnerState = new WinnerState(this); this.count = numberGumballs;
if (numberGumballs > 0)
state = noQuarterState;
this.location = location;
} public void insertQuarter() {
state.insertQuarter();
} public void ejectQuarter() {
state.ejectQuarter();
} public void turnCrank() {
state.turnCrank();
state.dispense();
} void setState(State state) {
this.state = state;
} void releaseBall() {
System.out.println("A gumball comes rolling out the slot...");
if (count != 0) {
count = count - 1;
}
} public void refill(int count) {
this.count = count;
state = noQuarterState;
} public int getCount() {
return count;
} public State getState() {
return state;
} public String getLocation() {
return location;
} //其它方法
} //在RMI register中注冊
public class GumballMachineTestDrive { public static void main(String[] args) {
GumballMachineRemote gumballMachine = null;
int count; if (args.length < 2) {
System.out.println("GumballMachine <name> <inventory>");
System.exit(1);
} try {//须要在实例化代码前加上try/catch。由于我们的构造器可能会抛出异常
count = Integer.parseInt(args[1]); gumballMachine = new GumballMachine(args[0], count); //我们也加入上对Naming.rebind的调用。用gumballmachine的名字公布GumballMachine的stub
Naming.rebind("//" + args[0] + "/gumballmachine", gumballMachine);
} catch (Exception e) {
e.printStackTrace();
}
}
} //GumballMonitorclient
public class GumballMonitor {
//依赖此GumballMachineRemote远程接口,而不是详细的类
GumballMachineRemote machine; public GumballMonitor(GumballMachineRemote machine) {
this.machine = machine;
} public void report() {
//当我们视图调用哪些终于都要通过网络发生的方法时,我么须要捕获全部可能发生的远程异常
try {
System.out.println("Gumball Machine: " + machine.getLocation());
System.out.println("Current inventory: " + machine.getCount()
+ " gumballs");
System.out.println("Current state: " + machine.getState());
} catch (RemoteException e) {
e.printStackTrace();
}
}
} //监视測试程序
public class GumballMonitorTestDrive { public static void main(String[] args) {
String[] location = { "rmi://santafe.mightygumball.com/gumballmachine",
"rmi://boulder.mightygumball.com/gumballmachine",
"rmi://seattle.mightygumball.com/gumballmachine" }; GumballMonitor[] monitor = new GumballMonitor[location.length]; for (int i = 0; i < location.length; i++) {
try {
//为每一个远程机器创建一个代理,客户从Register中寻找代理,也就是stub对象
GumballMachineRemote machine = (GumballMachineRemote) Naming
.lookup(location[i]);
monitor[i] = new GumballMonitor(machine);
System.out.println(monitor[i]);
} catch (Exception e) {
e.printStackTrace();
}
} //遍历每台机器,打印报告
for (int i = 0; i < monitor.length; i++) {
monitor[i].report();
}
}
}
class ImageProxy implements Icon {
ImageIcon imageIcon;
URL imageURL;
Thread retrievalThread;
boolean retrieving = false;
//我们将图像的url传入构造器中,这是我们希望显示的图像所在的位置
public ImageProxy(URL url) { imageURL = url; }
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) {
if (imageIcon != null) {
//假设已经有了icon,就告诉它画出自己
imageIcon.paintIcon(c, g, x, y);
} else {
g.drawString("Loading CD cover, please wait...", x+300, y+190);
if (!retrieving) {//假设我们还没试着取出图像
retrieving = true;
//我们不希望整个用户界面被挂起。所以用还有一个线程取出图像
retrievalThread = new Thread(new Runnable() {
public void run() {
try {
//此线程中我们实例化icon对象。其构造器会在图像载入完毕后才返回
imageIcon = new ImageIcon(imageURL, "CD Cover");
//当图像准备好后,我们告诉Swing须要重绘
c.repaint();
} catch (Exception e) {
e.printStackTrace();
}
}
});
retrievalThread.start();
}
}
}
}
public class ImageProxyTestDrive {
ImageComponent imageComponent;
JFrame frame = new JFrame("CD Cover Viewer");
JMenuBar menuBar;
JMenu menu;
Hashtable<String, String> cds = new Hashtable<String, String>();
public static void main(String[] args) throws Exception {
ImageProxyTestDrive testDrive = new ImageProxyTestDrive();
}
public ImageProxyTestDrive() throws Exception {
//建立框架和菜单
//创建一个图像代理,并指定初始URL
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 getCDUrl(String name) {
try {
return new URL((String) cds.get(name));
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
}
}
}
《Head First 设计模式》学习笔记——代理模式的更多相关文章
- Java-马士兵设计模式学习笔记-代理模式-聚合与继承方式比较
一.概述 1.目标:要在Tank的move()方法做时间代理及日志代理(可以设想以后还要增加很多代理处理),且代理间的顺序可活更换 2.思路: (1)聚合:代理类聚合了被代理类,且代理类及被代理类都实 ...
- Java-马士兵设计模式学习笔记-代理模式-动态代理 调用Proxy.newProxyInstance()
一.概述 1.目标:不自己写代理类,利用Proxy.newProxyInstance()动态生成 2.用到的知识点: (1)//编译源码,生成class,注意编译环境要换成jdk才有compiler, ...
- Java-马士兵设计模式学习笔记-代理模式-动态代理 修改成可以任意修改代理逻辑
一.概述 1.目标:动态代理的代理逻辑可以任意修改 2.思路: (1)要把代理逻辑抽离,站在jvm的角度思考,应独立出InvocationHandler接口,并接收被代理的对象及方法作为参数invok ...
- 设计模式学习心得<代理模式 Proxy>
在代理模式(Proxy Pattern)中,一个类代表另一个类的功能.这种类型的设计模式属于结构型模式. 在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口. 概述 意图 为其他对象提供 ...
- Java设计模式学习记录-代理模式
代理模式 代理模式是常见设计模式的一种,代理模式的定义是:为其他对象提供一种代理以控制对这个对象的访问. 在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起 ...
- 设计模式学习之代理模式(Proxy,结构型模式)(11)
参考地址:http://www.cnblogs.com/zhili/p/ProxyPattern.html 一.引言 在软件开发过程中,有些对象有时候会由于网络或其他的障碍,以至于不能够或者不能直接访 ...
- javascript设计模式学习之六——代理模式
一.代理模式定义 代理模式的关键是:当客户不方便直接访问一个对象或者不满足需要的时候,提供一个替身对象来控制对这个对象的访问.代理模式需要和本体对外提供相同的接口,对用户来说是透明的.代理模式的种类有 ...
- 学习笔记——代理模式Proxy
代理模式,主要是逻辑和实现解耦.具体逻辑如何,由代理Proxy自己来设计,我们只需要把逻辑Subject交给代理即可. 主要应用场景,包括创建大开销对象时,使用代理来慢慢创建:远程代理,如网络不确定时 ...
- 设计模式之笔记--代理模式(Proxy)
代理模式(Proxy) 定义 代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问. 类图 描述 Subject,定义了ConcreteSubject和Proxy的共用接口,这样就可以 ...
随机推荐
- Acunetix Web Vulnerability Scanner使用和生成报告的方法
Acunetix WVS,该扫描软件的全称Acunetix Web Vulnerability Scanner,是一个网站及服务器漏洞扫描软件.它可以检查Web应用程序中的漏洞,如SQL注入.跨站脚本 ...
- vc++中 .H 头文件引用的顺序与符号关系
在使用 #include "math.h" 和 #include <math.h>时,引号 与尖括号的区别如下 此时math.h_1 在工程文件中 math.h_2 ...
- sql常用手法(二)
drop,TRUNCATE和delete的区别 1.DROP删表,表结构将删了,当然数据也不存在了2.TRUNCATE和DELETE删数据,表结构还在3.DELETE可以带条件删除,TRUNCATE是 ...
- Scrapy 组件的具体用法
一.Spider 用法 在 Scrapy 中,要抓取网站的链接配置.抓取逻辑.解析逻辑都是在 Spider 里完成的.Spider 的一些基础属性和基础方法: name:爬虫名字,Spider的名字定 ...
- ie7下设置z-index无效如何解决?
ie7下z-index无效的问题之前做练习的时候遇到过,百度解决掉之后就丢脑后了.今天项目中又发现这个bug,无奈又去百度,这次还是记下来,节省了百度的时间还能小装一把... 需求是这样的: 页面中的 ...
- 「 HDU P3555 」 Bomb
# 题目大意 给出 $\text{T}$ 个数,求 $[1,n]$ 中含 ‘49’ 的数的个数. # 解题思路 求出不含 '49' 的数的个数,用总数减去就是答案. 数位 $DP$,用记忆化来做. 设 ...
- 「 COGS 2240 」 X 「 Luogu P2885 」 架设电话线
解题思路 首先很容易就想到了一个二维的朴素的 $dp$. 设 $dp[i][j]$ 表示第 $i$ 个位置的电话线杆的高度为 $j$ 时的最小花费,就需要枚举第 $i$ 个电话线杆.第 $i$ 个电话 ...
- zend studio 12.5.1 window 安装并设置笔记
下载百度云上的安装包-----------------------------------------------安装时,解决window 10的权限问题 安装完成后的设置设置字体window=> ...
- 三 , lnmp 一键包安装使用
安装打包环境 #https://lnmp.org/----------------------------------------------------#安装wget -c http://soft ...
- 【01】CSS制作的图形
[01]CSS制作的图形 绘制五角星: 通过border绘制三角形.然后通过transfrom来旋转35度. 绘制对称的图形,最后绘制顶部的三角形即可. 元素本身,加上:before和:a ...