设计模式--代理模式

                 设计模式--代理模式

 

代理模式原理
·远程糖果机监控项目

监控糖果机:地点、糖果库存和当前状态
本地糖果机监控怎么做

`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();
	}


}



·几种变体
防火墙代理
缓存代理
智能引用代理
同步代理
写入时复制代理