设计模式--代理模式
设计模式--代理模式
代理模式原理
·远程糖果机监控项目
监控糖果机:地点、糖果库存和当前状态
本地糖果机监控怎么做
`CandyMachine的类由上篇博文状态模式的案例继续下来
Monitor
import java.util.ArrayList;
public class Monitor {
private ArrayList<CandyMachine> candyMachinelst;
public Monitor() {
candyMachinelst = new ArrayList<CandyMachine>();
}
public void addMachine(CandyMachine mCandyMachine) {
candyMachinelst.add(mCandyMachine);
}
public void report() {
CandyMachine mCandyMachine;
for (int i = 0, len = candyMachinelst.size(); i < len; i++) {
mCandyMachine = candyMachinelst.get(i);
System.out.println("Machine Loc:" + mCandyMachine.getLocation());
System.out.println("Machine Candy count:"
+ mCandyMachine.getCount());
System.out.println("Machine State:"
+ mCandyMachine.getstate().getstatename());
}
}
}
MainTest
public class MainTest {
public static void main(String[] args) throws RemoteException {
Monitor mMonitor=new Monitor();
CandyMachine mCandyMachine = new CandyMachine("NY",6);
mMonitor.addMachine(mCandyMachine);
mCandyMachine = new CandyMachine("TK",4);
mCandyMachine.insertCoin();
mMonitor.addMachine(mCandyMachine);
mCandyMachine = new CandyMachine("Bj",14);
mCandyMachine.insertCoin();
mCandyMachine.turnCrank();
mMonitor.addMachine(mCandyMachine);
mMonitor.report();
}
}
远程糖果机监控困难在哪
有哪些方案
·代理监控方案
远程代理:远程对象的本地代表,通过它可以让远程对象当本地对象来调用。
远程代理通过网络和真正的远程对象沟通信息。
·方案结构图
利用Java RMI实现远程代理:
·代理模式原理
代理模式:为一个对象提供一个替身,以控制对这个对象的访问
被代理的对象可以是远程对象、创建开销大的对象或需要安全控制的对象
代理模式有很多变体,都是为了控制与管理对象访问
Java RMI介绍
RMI概要
RMI远程方法调用是计算机之间通过网络实现对象调用的一种通讯机制。
使用这种机制,一台计算机上的对象可以调用另外 一台计算机上的对象来获取远
程数据。
在过去,TCP/IP通讯是远程通讯的主要手段,面向过程的开发。
而RPC使程序员更容易地调用远程程序,但在面对复杂的信息传讯时,RPC依然
未能很好的支持
RMI被设计成一种面向对象开发方式,允许程序员使用远程对象来实现通信
·RMI使用介绍
制作远程接口:接口文件
远程接口的实现:Service文件
RMI服务端注册,开启服务
RMI代理端通过RMI查询到服务端,建立联系,通过接口调用远程方法
·代码讲解
MyRemote
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface MyRemote extends Remote{
public String sayHello() throws RemoteException;
}
MyRemoteImpl
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;
@SuppressWarnings("serial")
public class MyRemoteImpl extends UnicastRemoteObject implements MyRemote{
protected MyRemoteImpl() throws RemoteException {
super();
// TODO Auto-generated constructor stub
}
@Override
public String sayHello() throws RemoteException {
// TODO Auto-generated method stub
return "Hello World!";
}
public static void main(String[] args) {
try {
MyRemote service=new MyRemoteImpl();
// LocateRegistry.createRegistry(6600);
Naming.rebind("rmi://127.0.0.1:6600/RemoteHello", service);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println( e.toString());
}
}
}
MyRemoteClient
import java.rmi.Naming;
public class MyRemoteClient {
public static void main(String[] args) {
new MyRemoteClient().go();
}
public void go()
{
try {
MyRemote service=(MyRemote)Naming.lookup("rmi://127.0.0.1:6600/RemoteHello");
String s=service.sayHello();
System.out.println(s);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
代理模式示例代码讲解
示例项目类结构图
·
CandyMachineRemote
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface CandyMachineRemote extends Remote{
public String getLocation() throws RemoteException;
public int getCount() throws RemoteException;
public State getstate() throws RemoteException;
}
State
import java.io.Serializable;
public interface State extends Serializable{
public void insertCoin();
public void returnCoin();
public void turnCrank();
public void dispense();
public void printstate();
public String getstatename();
}
CandyMachine
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class CandyMachine extends UnicastRemoteObject implements CandyMachineRemote{
State mSoldOutState;
State mOnReadyState;
State mHasCoin;
State mSoldState;
State mWinnerState;
private String location="";
private State state;
private int count = 0;
public CandyMachine(String location,int count) throws RemoteException{
this.location=location;
this.count = count;
mSoldOutState = new SoldOutState(this);
mOnReadyState = new OnReadyState(this);
mHasCoin = new HasCoin(this);
mSoldState = new SoldState(this);
mWinnerState = new WinnerState(this);
if (count > 0) {
state = mOnReadyState;
} else {
state = mSoldOutState;
}
}
public String getLocation()
{
return location;
}
public void setState(State state) {
this.state = state;
}
public void insertCoin() {
state.insertCoin();
}
public void returnCoin() {
state.returnCoin();
}
public void turnCrank() {
state.turnCrank();
state.dispense();
}
void releaseCandy() {
// TODO Auto-generated method stub
if (count > 0) {
count = count - 1;
System.out.println("a candy rolling out!");
}
}
public int getCount() {
return count;
}
public void printstate() {
state.printstate();
}
public State getstate() {
return state;
}
}
Monitor
import java.rmi.RemoteException;
import java.util.ArrayList;
public class Monitor {
private ArrayList<CandyMachineRemote> candyMachinelst;
public Monitor() {
candyMachinelst = new ArrayList<CandyMachineRemote>();
}
public void addMachine(CandyMachineRemote mCandyMachine) {
candyMachinelst.add(mCandyMachine);
}
public void report() {
CandyMachineRemote mCandyMachine;
for (int i = 0, len = candyMachinelst.size(); i < len; i++) {
mCandyMachine = candyMachinelst.get(i);
try {
System.out
.println("Machine Loc:" + mCandyMachine.getLocation());
System.out.println("Machine Candy count:"
+ mCandyMachine.getCount());
System.out.println("Machine State:"
+ mCandyMachine.getstate().getstatename());
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
RemoteMainTest
import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;
public class RemoteMainTest {
public static void main(String[] args) {
try {
CandyMachine service = new CandyMachine("test1", 7);
// LocateRegistry.createRegistry(6602);
Naming.rebind("rmi://127.0.0.1:6602/test1", service);
service.insertCoin();
service = new CandyMachine("test2", 5);
Naming.rebind("rmi://127.0.0.1:6602/test2", service);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println(e.toString());
}
}
}
几种常见的代理模式介绍
虚拟代理
虚拟代理为创建开销大的对象提供代理服务。
真正的对象在创建前和创建中时,由虚拟代理来扮演替身。
似乎很神秘,其实很简单
如:Android的在线图片加载类
·动态代理
动态代理:运行时动态的创建代理类,并将方法调用转发到指定类
看一个找对象项目:
约会服务系统代码讲解
·保护代理
保护代理:看一个找对象项目,个人信息、兴趣爱好、打分
PersonBean
public interface PersonBean {
String getName();
String getGender();
String getInterests();
int getHotOrNotRating();
void setName(String name);
void setGender(String gender);
void setInterests(String interests);
void setHotOrNotRating(int rating);
}
PersonBeanImpl
public class PersonBeanImpl implements PersonBean{
String name;
String gender;
String interests;
int rating;
int ratingcount=0;
@Override
public String getName() {
// TODO Auto-generated method stub
return name;
}
@Override
public String getGender() {
// TODO Auto-generated method stub
return gender;
}
@Override
public String getInterests() {
// TODO Auto-generated method stub
return interests;
}
@Override
public int getHotOrNotRating() {
// TODO Auto-generated method stub
if(ratingcount==0) return 0;
return (rating/ratingcount);
}
@Override
public void setName(String name) {
// TODO Auto-generated method stub
this.name=name;
}
@Override
public void setGender(String gender) {
// TODO Auto-generated method stub
this.gender=gender;
}
@Override
public void setInterests(String interests) {
// TODO Auto-generated method stub
this.interests=interests;
}
@Override
public void setHotOrNotRating(int rating) {
// TODO Auto-generated method stub
this.rating=rating;
ratingcount++;
}
}
OwnerInvocationHandler
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class OwnerInvocationHandler implements InvocationHandler{
PersonBean person;
public OwnerInvocationHandler(PersonBean person)
{
this.person=person;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
if(method.getName().startsWith("get"))
{
return method.invoke(person,args);
}else if(method.getName().equals("setHotOrNotRating"))
{
return new IllegalAccessException();
}else if(method.getName().startsWith("set"))
{
return method.invoke(person,args);
}
return null;
}
}
NonOwnerInvocationHandler
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class NonOwnerInvocationHandler implements InvocationHandler{
PersonBean person;
public NonOwnerInvocationHandler(PersonBean person)
{
this.person=person;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
if(method.getName().startsWith("get"))
{
return method.invoke(person,args);
}else if(method.getName().equals("setHotOrNotRating"))
{
return method.invoke(person,args);
}else if(method.getName().startsWith("set"))
{
return new IllegalAccessException();
}
return null;
}
}
MatchService
import java.lang.reflect.Proxy;
public class MatchService {
public MatchService() {
PersonBean joe = getPersonInfo("joe", "male", "running");
PersonBean OwnerProxy = getOwnerProxy(joe);
System.out.println("Name is " + OwnerProxy.getName());
System.out.println("Interests is " + OwnerProxy.getInterests());
OwnerProxy.setInterests("Bowling");
System.out.println("Interests are " + OwnerProxy.getInterests());
OwnerProxy.setHotOrNotRating(50);
System.out.println("Rating is " + OwnerProxy.getHotOrNotRating());
OwnerProxy.setHotOrNotRating(40);
System.out.println("Rating is " + OwnerProxy.getHotOrNotRating());
System.out.println("**************");
PersonBean nonOwnerProxy = getNonOwnerProxy(joe);
System.out.println("Name is " + nonOwnerProxy.getName());
System.out.println("Interests are " + nonOwnerProxy.getInterests());
nonOwnerProxy.setInterests("haha");
System.out.println("Interests are " + nonOwnerProxy.getInterests());
nonOwnerProxy.setHotOrNotRating(60);
System.out.println("Rating is " + nonOwnerProxy.getHotOrNotRating());
}
PersonBean getPersonInfo(String name, String gender, String interests) {
PersonBean person = new PersonBeanImpl();
person.setName(name);
person.setGender(gender);
person.setInterests(interests);
return person;
}
PersonBean getOwnerProxy(PersonBean person) {
return (PersonBean) Proxy.newProxyInstance(person.getClass()
.getClassLoader(), person.getClass().getInterfaces(),
new OwnerInvocationHandler(person));
}
PersonBean getNonOwnerProxy(PersonBean person) {
return (PersonBean) Proxy.newProxyInstance(person.getClass()
.getClassLoader(), person.getClass().getInterfaces(),
new NonOwnerInvocationHandler(person));
}
}
MainTest
public class MainTest {
public static void main(String[] args) {
MatchService mMatchService=new MatchService();
}
}
·几种变体
防火墙代理
缓存代理
智能引用代理
同步代理
写入时复制代理