代理模式:(为一个对象提供一个替身,以控制对这个对象的访问)
被代理的对象可以是远程对象、创建开销大的对象或需要安全控制的对象;代理模式有很多变体,都是为了控制与管理对象访问。
代理模式包含如下角色:
ISubject:抽象主题角色,是一个接口。该接口是对象和它的代理共用的接口。
RealSubject:真实主题角色,是实现抽象主题接口的类。
Proxy:代理角色,内部含有对真实对象RealSubject的引用,从而可以操作真实对象。代理对象提供与真实对象相同的接口,以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
实现动态代理的关键技术是反射。
例子:(通过这个例子,从不使用代理模式,到使用代理模式)
监控糖果机:地点、糖果库存和当前状态
ISubject:
1 package com.java.mmzs.agentmode.candymachine; 2 3 import java.io.Serializable; 4 5 public interface State extends Serializable{ 6 public void insertCoin(); 7 public void returnCoin(); 8 public void turnCrank(); 9 public void dispense(); 10 public void printstate(); 11 public String getstatename(); 12 }
1 package com.java.mmzs.agentmode.candymachinermi; 2 3 import java.rmi.Remote; 4 import java.rmi.RemoteException; 5 6 import com.java.mmzs.agentmode.candymachine.State; 7 8 public interface CandyMachineRemote extends Remote{ 9 public String getLocation() throws RemoteException; 10 public int getCount() throws RemoteException; 11 public State getstate() throws RemoteException; 12 }
RealSubject:
1 package com.java.mmzs.agentmode.candymachine; 2 3 public class OnReadyState implements State { 4 private transient CandyMachine mCandyMachine; 5 public OnReadyState(CandyMachine mCandyMachine) 6 { 7 this.mCandyMachine=mCandyMachine; 8 } 9 10 @Override 11 public void insertCoin() { 12 // TODO Auto-generated method stub 13 System.out 14 .println("you have inserted a coin,next,please turn crank!"); 15 mCandyMachine.setState(mCandyMachine.mHasCoin); 16 } 17 18 @Override 19 public void returnCoin() { 20 // TODO Auto-generated method stub 21 System.out.println("you haven't inserted a coin yet!"); 22 23 } 24 25 @Override 26 public void turnCrank() { 27 // TODO Auto-generated method stub 28 System.out.println("you turned,but you haven't inserted a coin!"); 29 30 } 31 32 @Override 33 public void dispense() { 34 // TODO Auto-generated method stub 35 36 } 37 38 @Override 39 public void printstate() { 40 // TODO Auto-generated method stub 41 System.out.println("***OnReadyState***"); 42 43 } 44 @Override 45 public String getstatename() { 46 // TODO Auto-generated method stub 47 return "OnReadyState"; 48 } 49 }
1 package com.java.mmzs.agentmode.candymachine; 2 3 import java.util.Random; 4 5 public class HasCoin implements State { 6 private transient CandyMachine mCandyMachine; 7 8 public HasCoin(CandyMachine mCandyMachine) { 9 this.mCandyMachine = mCandyMachine; 10 } 11 12 @Override 13 public void insertCoin() { 14 // TODO Auto-generated method stub 15 System.out.println("you can't insert another coin!"); 16 17 } 18 19 @Override 20 public void returnCoin() { 21 // TODO Auto-generated method stub 22 System.out.println("coin return!"); 23 mCandyMachine.setState(mCandyMachine.mOnReadyState); 24 } 25 26 @Override 27 public void turnCrank() { 28 // TODO Auto-generated method stub 29 System.out.println("crank turn...!"); 30 Random ranwinner=new Random(); 31 int winner=ranwinner.nextInt(10); 32 if(winner==0) 33 { 34 mCandyMachine.setState(mCandyMachine.mWinnerState); 35 36 }else 37 { 38 mCandyMachine.setState(mCandyMachine.mSoldState); 39 40 } 41 42 } 43 44 @Override 45 public void dispense() { 46 } 47 48 @Override 49 public void printstate() { 50 // TODO Auto-generated method stub 51 System.out.println("***HasCoin***"); 52 53 } 54 55 @Override 56 public String getstatename() { 57 // TODO Auto-generated method stub 58 return "HasCoin State"; 59 } 60 61 }
1 package com.java.mmzs.agentmode.candymachine; 2 3 public class SoldState implements State { 4 private transient CandyMachine mCandyMachine; 5 public SoldState(CandyMachine mCandyMachine) 6 { 7 this.mCandyMachine=mCandyMachine; 8 } 9 10 @Override 11 public void insertCoin() { 12 // TODO Auto-generated method stub 13 System.out.println("please wait!we are giving you a candy!"); 14 15 } 16 17 @Override 18 public void returnCoin() { 19 // TODO Auto-generated method stub 20 System.out.println("you haven't inserted a coin yet!"); 21 22 } 23 24 @Override 25 public void turnCrank() { 26 // TODO Auto-generated method stub 27 System.out 28 .println("we are giving you a candy,turning another get nothing,!"); 29 30 } 31 32 @Override 33 public void dispense() { 34 // TODO Auto-generated method stub 35 36 mCandyMachine.releaseCandy(); 37 if (mCandyMachine.getCount() > 0) { 38 mCandyMachine.setState(mCandyMachine.mOnReadyState); 39 } else { 40 System.out.println("Oo,out of candies"); 41 mCandyMachine.setState(mCandyMachine.mSoldOutState); 42 } 43 44 45 46 } 47 48 @Override 49 public void printstate() { 50 // TODO Auto-generated method stub 51 System.out.println("***SoldState***"); 52 53 } 54 @Override 55 public String getstatename() { 56 // TODO Auto-generated method stub 57 return "SoldState"; 58 } 59 }
1 package com.java.mmzs.agentmode.candymachine; 2 3 public class SoldOutState implements State { 4 5 private transient CandyMachine mCandyMachine; 6 public SoldOutState(CandyMachine mCandyMachine) 7 { 8 this.mCandyMachine=mCandyMachine; 9 } 10 11 @Override 12 public void insertCoin() { 13 // TODO Auto-generated method stub 14 System.out.println("you can't insert coin,the machine sold out!"); 15 16 } 17 18 @Override 19 public void returnCoin() { 20 // TODO Auto-generated method stub 21 System.out 22 .println("you can't return,you haven't inserted a coin yet!"); 23 24 } 25 26 @Override 27 public void turnCrank() { 28 // TODO Auto-generated method stub 29 System.out.println("you turned,but there are no candies!"); 30 31 } 32 33 @Override 34 public void dispense() { 35 // TODO Auto-generated method stub 36 37 } 38 39 @Override 40 public void printstate() { 41 // TODO Auto-generated method stub 42 System.out.println("***SoldOutState***"); 43 44 } 45 @Override 46 public String getstatename() { 47 // TODO Auto-generated method stub 48 return "SoldOutState"; 49 } 50 }
1 package com.java.mmzs.agentmode.candymachine; 2 3 public class WinnerState implements State { 4 5 private transient CandyMachine mCandyMachine; 6 7 public WinnerState(CandyMachine mCandyMachine) { 8 this.mCandyMachine = mCandyMachine; 9 } 10 11 @Override 12 public void insertCoin() { 13 // TODO Auto-generated method stub 14 System.out.println("please wait!we are giving you a candy!"); 15 16 } 17 18 @Override 19 public void returnCoin() { 20 // TODO Auto-generated method stub 21 System.out.println("you haven't inserted a coin yet!"); 22 23 } 24 25 @Override 26 public void turnCrank() { 27 // TODO Auto-generated method stub 28 System.out 29 .println("we are giving you a candy,turning another get nothing,!"); 30 31 } 32 33 @Override 34 public void dispense() { 35 // TODO Auto-generated method stub 36 37 38 mCandyMachine.releaseCandy(); 39 if (mCandyMachine.getCount() == 0) { 40 mCandyMachine.setState(mCandyMachine.mSoldOutState); 41 } else { 42 System.out.println("you are a winner!you get another candy!"); 43 mCandyMachine.releaseCandy(); 44 if (mCandyMachine.getCount() > 0) { 45 mCandyMachine.setState(mCandyMachine.mOnReadyState); 46 } else { 47 System.out.println("Oo,out of candies"); 48 mCandyMachine.setState(mCandyMachine.mSoldOutState); 49 } 50 } 51 52 } 53 54 @Override 55 public void printstate() { 56 // TODO Auto-generated method stub 57 System.out.println("***WinnerState***"); 58 59 } 60 @Override 61 public String getstatename() { 62 // TODO Auto-generated method stub 63 return "WinnerState"; 64 } 65 }
1 package com.java.mmzs.agentmode.candymachine; 2 3 import java.rmi.RemoteException; 4 import java.rmi.server.UnicastRemoteObject; 5 6 import com.java.mmzs.agentmode.candymachinermi.CandyMachineRemote; 7 8 public class CandyMachine extends UnicastRemoteObject implements CandyMachineRemote{ 9 10 State mSoldOutState; 11 State mOnReadyState; 12 State mHasCoin; 13 State mSoldState; 14 State mWinnerState; 15 private String location=""; 16 private State state; 17 private int count = 0; 18 19 public CandyMachine(String location,int count) throws RemoteException{ 20 this.location=location; 21 this.count = count; 22 mSoldOutState = new SoldOutState(this); 23 mOnReadyState = new OnReadyState(this); 24 mHasCoin = new HasCoin(this); 25 mSoldState = new SoldState(this); 26 mWinnerState = new WinnerState(this); 27 if (count > 0) { 28 state = mOnReadyState; 29 } else { 30 state = mSoldOutState; 31 } 32 } 33 public String getLocation() 34 { 35 return location; 36 } 37 public void setState(State state) { 38 this.state = state; 39 } 40 41 public void insertCoin() { 42 state.insertCoin(); 43 } 44 45 public void returnCoin() { 46 state.returnCoin(); 47 } 48 49 public void turnCrank() { 50 state.turnCrank(); 51 state.dispense(); 52 } 53 54 void releaseCandy() { 55 56 // TODO Auto-generated method stub 57 if (count > 0) { 58 count = count - 1; 59 System.out.println("a candy rolling out!"); 60 } 61 62 } 63 64 public int getCount() { 65 return count; 66 } 67 68 public void printstate() { 69 state.printstate(); 70 } 71 public State getstate() { 72 return state; 73 } 74 }
不使用代理:
1 package com.java.mmzs.agentmode; 2 3 import java.util.ArrayList; 4 5 import com.java.mmzs.agentmode.candymachine.CandyMachine; 6 7 public class Monitor { 8 private ArrayList<CandyMachine> candyMachinelst; 9 10 public Monitor() { 11 candyMachinelst = new ArrayList<CandyMachine>(); 12 } 13 14 public void addMachine(CandyMachine mCandyMachine) { 15 candyMachinelst.add(mCandyMachine); 16 } 17 18 public void report() { 19 CandyMachine mCandyMachine; 20 for (int i = 0, len = candyMachinelst.size(); i < len; i++) { 21 mCandyMachine = candyMachinelst.get(i); 22 System.out.println("Machine Loc:" + mCandyMachine.getLocation()); 23 System.out.println("Machine Candy count:" 24 + mCandyMachine.getCount()); 25 System.out.println("Machine State:" 26 + mCandyMachine.getstate().getstatename()); 27 28 } 29 30 } 31 32 }
1 package com.java.mmzs.agentmode; 2 3 import java.rmi.RemoteException; 4 5 import com.java.mmzs.agentmode.candymachine.CandyMachine; 6 7 public class MainTest { 8 public static void main(String[] args) throws RemoteException { 9 Monitor mMonitor=new Monitor(); 10 CandyMachine mCandyMachine = new CandyMachine("NY",6); 11 mMonitor.addMachine(mCandyMachine); 12 13 mCandyMachine = new CandyMachine("TK",4); 14 mCandyMachine.insertCoin(); 15 mMonitor.addMachine(mCandyMachine); 16 17 mCandyMachine = new CandyMachine("Bj",14); 18 mCandyMachine.insertCoin(); 19 mCandyMachine.turnCrank(); 20 mMonitor.addMachine(mCandyMachine); 21 22 mMonitor.report(); 23 } 24 }
下面介绍一种代理RMI:
RMI远程方法调用是计算机之间通过网络实现对象调用的一种通讯机制。 使用这种机制,一台计算机上的对象可以调用另外 一台计算机上的对象来获取远程数据。 在过去,TCP/IP通讯是远程通讯的主要手段,面向过程的开发。 而RPC使程序员更容易地调用远程程序,但在面对复杂的信息传讯时,RPC依然未能很好的支持。
RMI被设计成一种面向对象开发方式,允许程序员使用远程对象来实现通信,
使用流程:
制作远程接口:接口文件
远程接口的实现:Service文件
RMI服务端注册,开启服务
RMI代理端通过RMI查询到服务端,建立联系,通过接口调用远程方法
1 package com.java.mmzs.agentmode.rmi; 2 3 import java.rmi.Remote; 4 import java.rmi.RemoteException; 5 6 public interface MyRemote extends Remote{ 7 8 public String sayHello() throws RemoteException; 9 10 }
package com.java.mmzs.agentmode.rmi; 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()); } } }
1 package com.java.mmzs.agentmode.rmi; 2 3 import java.rmi.Naming; 4 5 public class MyRemoteClient { 6 public static void main(String[] args) { 7 8 new MyRemoteClient().go(); 9 } 10 11 public void go() 12 { 13 try { 14 MyRemote service=(MyRemote)Naming.lookup("rmi://127.0.0.1:6600/RemoteHello"); 15 String s=service.sayHello(); 16 System.out.println(s); 17 18 } catch (Exception e) { 19 // TODO Auto-generated catch block 20 e.printStackTrace(); 21 } 22 } 23 }
接下来使用RMI改造糖果机的例子:
1 package com.java.mmzs.agentmode.candymachinermi; 2 3 import java.rmi.Remote; 4 import java.rmi.RemoteException; 5 6 import com.java.mmzs.agentmode.candymachine.State; 7 8 public interface CandyMachineRemote extends Remote{ 9 public String getLocation() throws RemoteException; 10 public int getCount() throws RemoteException; 11 public State getstate() throws RemoteException; 12 }
1 package com.java.mmzs.agentmode.candymachinermi; 2 3 import java.rmi.RemoteException; 4 import java.util.ArrayList; 5 6 import com.java.mmzs.agentmode.candymachine.CandyMachine; 7 8 public class Monitor { 9 10 private ArrayList<CandyMachineRemote> candyMachinelst; 11 12 public Monitor() { 13 candyMachinelst = new ArrayList<CandyMachineRemote>(); 14 } 15 16 public void addMachine(CandyMachineRemote mCandyMachine) { 17 candyMachinelst.add(mCandyMachine); 18 } 19 20 public void report() { 21 CandyMachineRemote mCandyMachine; 22 for (int i = 0, len = candyMachinelst.size(); i < len; i++) { 23 mCandyMachine = candyMachinelst.get(i); 24 try { 25 System.out 26 .println("Machine Loc:" + mCandyMachine.getLocation()); 27 28 System.out.println("Machine Candy count:" 29 + mCandyMachine.getCount()); 30 System.out.println("Machine State:" 31 + mCandyMachine.getstate().getstatename()); 32 } catch (RemoteException e) { 33 // TODO Auto-generated catch block 34 e.printStackTrace(); 35 } 36 } 37 38 } 39 40 }
1 package com.java.mmzs.agentmode.candymachinermi; 2 3 import java.rmi.Naming; 4 import java.rmi.registry.LocateRegistry; 5 6 import com.java.mmzs.agentmode.candymachine.CandyMachine; 7 import com.java.mmzs.agentmode.rmi.MyRemote; 8 import com.java.mmzs.agentmode.rmi.MyRemoteImpl; 9 10 public class RemoteMainTest { 11 public static void main(String[] args) { 12 13 try { 14 CandyMachine service = new CandyMachine("test1", 7); 15 // LocateRegistry.createRegistry(6602); 16 Naming.rebind("rmi://127.0.0.1:6602/test1", service); 17 service.insertCoin(); 18 service = new CandyMachine("test2", 5); 19 Naming.rebind("rmi://127.0.0.1:6602/test2", service); 20 } catch (Exception e) { 21 // TODO Auto-generated catch block 22 e.printStackTrace(); 23 System.out.println(e.toString()); 24 } 25 26 } 27 }
1 package com.java.mmzs.agentmode.candymachinermi; 2 3 import java.rmi.Naming; 4 5 import com.java.mmzs.agentmode.candymachine.CandyMachine; 6 import com.java.mmzs.agentmode.rmi.MyRemote; 7 8 public class MainTest { 9 10 public static void main(String[] args) { 11 Monitor mMonitor = new Monitor(); 12 13 try { 14 CandyMachineRemote mCandyMachine = (CandyMachineRemote) Naming 15 .lookup("rmi://127.0.0.1:6602/test1"); 16 mMonitor.addMachine(mCandyMachine); 17 mCandyMachine = (CandyMachineRemote) Naming 18 .lookup("rmi://127.0.0.1:6602/test2"); 19 mMonitor.addMachine(mCandyMachine); 20 } catch (Exception e) { 21 // TODO Auto-generated catch block 22 e.printStackTrace(); 23 } 24 25 mMonitor.report(); 26 } 27 28 }
几种常见的代理模式介绍:
虚拟代理:
虚拟代理为创建开销大的对象提供代理服务。 真正的对象在创建前和创建中时,由虚拟代理来扮演替身。
似乎很神秘,其实很简单 如:Android的在线图片加载类;
动态代理:可参照这篇文章
运行时动态的创建代理类,并将方法调用转发到指定类;
有n各主题类,但是代理类中的“前处理、后处理”都是一样的,仅调用主题不同。也就是说,多个主题类对应一个代理类,共享“前处理,后处理”功能,动态调用所需主题,大大减小了程序规模,这就是动态代理模式的特点。
看一个找对象项目: 约会服务系统代码讲解
1 package com.java.mmzs.agentmode.dyn; 2 3 public interface PersonBean { 4 String getName(); 5 String getGender(); 6 String getInterests(); 7 int getHotOrNotRating(); 8 9 void setName(String name); 10 void setGender(String gender); 11 void setInterests(String interests); 12 void setHotOrNotRating(int rating); 13 }
1 package com.java.mmzs.agentmode.dyn; 2 3 public class PersonBeanImpl implements PersonBean{ 4 String name; 5 String gender; 6 String interests; 7 int rating; 8 int ratingcount=0; 9 @Override 10 public String getName() { 11 // TODO Auto-generated method stub 12 return name; 13 } 14 15 @Override 16 public String getGender() { 17 // TODO Auto-generated method stub 18 return gender; 19 } 20 21 @Override 22 public String getInterests() { 23 // TODO Auto-generated method stub 24 return interests; 25 } 26 27 @Override 28 public int getHotOrNotRating() { 29 // TODO Auto-generated method stub 30 if(ratingcount==0) return 0; 31 return (rating/ratingcount); 32 } 33 34 @Override 35 public void setName(String name) { 36 // TODO Auto-generated method stub 37 this.name=name; 38 } 39 40 @Override 41 public void setGender(String gender) { 42 // TODO Auto-generated method stub 43 this.gender=gender; 44 } 45 46 @Override 47 public void setInterests(String interests) { 48 // TODO Auto-generated method stub 49 this.interests=interests; 50 } 51 52 @Override 53 public void setHotOrNotRating(int rating) { 54 // TODO Auto-generated method stub 55 this.rating=rating; 56 ratingcount++; 57 } 58 59 }
1 package com.java.mmzs.agentmode.dyn; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.InvocationTargetException; 5 import java.lang.reflect.Method; 6 7 public class NonOwnerInvocationHandler implements InvocationHandler{ 8 PersonBean person; 9 public NonOwnerInvocationHandler(PersonBean person) 10 { 11 this.person=person; 12 } 13 @Override 14 public Object invoke(Object proxy, Method method, Object[] args) 15 throws Throwable { 16 // TODO Auto-generated method stub 17 18 if(method.getName().startsWith("get")) 19 { 20 return method.invoke(person,args); 21 }else if(method.getName().equals("setHotOrNotRating")) 22 { 23 return method.invoke(person,args); 24 25 }else if(method.getName().startsWith("set")) 26 { 27 return new IllegalAccessException(); 28 } 29 30 return null; 31 } 32 33 }
1 package com.java.mmzs.agentmode.dyn; 2 3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.InvocationTargetException; 5 import java.lang.reflect.Method; 6 7 public class OwnerInvocationHandler implements InvocationHandler{ 8 PersonBean person; 9 public OwnerInvocationHandler(PersonBean person) 10 { 11 this.person=person; 12 } 13 @Override 14 public Object invoke(Object proxy, Method method, Object[] args) 15 throws Throwable { 16 // TODO Auto-generated method stub 17 18 if(method.getName().startsWith("get")) 19 { 20 return method.invoke(person,args); 21 }else if(method.getName().equals("setHotOrNotRating")) 22 { 23 return new IllegalAccessException(); 24 }else if(method.getName().startsWith("set")) 25 { 26 return method.invoke(person,args); 27 } 28 29 return null; 30 } 31 32 }
1 package com.java.mmzs.agentmode.dyn; 2 3 import java.lang.reflect.Proxy; 4 5 public class MatchService { 6 public MatchService() { 7 8 PersonBean joe = getPersonInfo("joe", "male", "running"); 9 10 PersonBean OwnerProxy = getOwnerProxy(joe); 11 12 System.out.println("Name is " + OwnerProxy.getName()); 13 System.out.println("Interests is " + OwnerProxy.getInterests()); 14 15 OwnerProxy.setInterests("Bowling"); 16 System.out.println("Interests are " + OwnerProxy.getInterests()); 17 OwnerProxy.setHotOrNotRating(50); 18 System.out.println("Rating is " + OwnerProxy.getHotOrNotRating()); 19 OwnerProxy.setHotOrNotRating(40); 20 System.out.println("Rating is " + OwnerProxy.getHotOrNotRating()); 21 22 System.out.println("**************"); 23 24 PersonBean nonOwnerProxy = getNonOwnerProxy(joe); 25 System.out.println("Name is " + nonOwnerProxy.getName()); 26 System.out.println("Interests are " + nonOwnerProxy.getInterests()); 27 nonOwnerProxy.setInterests("haha"); 28 System.out.println("Interests are " + nonOwnerProxy.getInterests()); 29 nonOwnerProxy.setHotOrNotRating(60); 30 System.out.println("Rating is " + nonOwnerProxy.getHotOrNotRating()); 31 32 } 33 34 PersonBean getPersonInfo(String name, String gender, String interests) { 35 PersonBean person = new PersonBeanImpl(); 36 person.setName(name); 37 person.setGender(gender); 38 person.setInterests(interests); 39 return person; 40 } 41 42 PersonBean getOwnerProxy(PersonBean person) { 43 return (PersonBean) Proxy.newProxyInstance(person.getClass() 44 .getClassLoader(), person.getClass().getInterfaces(), 45 new OwnerInvocationHandler(person)); 46 } 47 48 PersonBean getNonOwnerProxy(PersonBean person) { 49 return (PersonBean) Proxy.newProxyInstance(person.getClass() 50 .getClassLoader(), person.getClass().getInterfaces(), 51 new NonOwnerInvocationHandler(person)); 52 } 53 }
1 package com.java.mmzs.agentmode.dyn; 2 3 4 public class MainTest { 5 6 7 public static void main(String[] args) { 8 9 MatchService mMatchService=new MatchService(); 10 } 11 12 13 }
保护代理:
当我们想要隐藏某个类时,可以为其提供代理类;
类似房屋中介,相亲平台,代理律师;
1 public interface ZiRanRen { 2 void Quanli(); 3 }
1 public class Consigner implements ZiRanRen { 2 public void eat() { 3 System.out.println("吃饭"); 4 } 5 public void drink() { 6 System.out.println("喝水"); 7 } 8 @Override 9 public void Quanli() { 10 System.out.println("我赋予我的代理律师来行使这些权利,此时代理律师全权代理我处理某些事务"); 11 } 12 }
1 public class Lawyer implements ZiRanRen { 2 @Override 3 public void Quanli() { 4 new Consigner().Quanli(); 5 } 6 }
1 public class Clienter { 2 public static void main(String[] args) { 3 ZiRanRen lawyer = new Lawyer(); 4 lawyer.Quanli(); 5 } 6 }
可以看出,我们想对外开放某些功能,就可以将这些功能在代理类中被引用;如此一来,屏蔽了我们不想外露的功能,只将我们想开放的功能开放出来。亦即委托类中其实是可以有很多方法的,很多功能的,我们可以酌情对外开放,代理类犹如一道大门,将委托类与外部调用者隔绝开来,只将部分功能赋予这个大门,来代替委托类行使这个功能,哪怕最终还是要牵扯到自身(因为最终还是要调用委托类的对应方法实现)。
几种变体:
防火墙代理
缓存代理
智能引用代理
同步代理
写入时复制代理
优点:
(1)代理类与委托类(被代理类)都实现了同一个接口,可实现灵活多变;继承式的实现方式则不够灵活;
(2)在委托类中实现功能,在代理类的方法中中引用委托类的同名方法;
(3)外部类调用委托类某个方法时,直接以接口指向代理类的实例,这正是代理的意义所在:屏蔽。
缺点:
代理模式虽然实现了调用者与委托类之间的强耦合,但是却增加了代理类与委托类之间的强耦合(在代理类中显式调用委托类的方法),而且增加代理类之后明显会增加处理时间,拖慢处理时间。
欢迎加群一起交流:603654340
应用场景:
(1)当我们想要隐藏某个类时,可以为其提供代理类;
(2)当一个类需要对不同的调用者提供不同的调用权限时,可以使用代理类来实现(代理类不一定只有一个,我们可以建立多个代理类来实现,也可以在一个代理类中金进行权限判断来进行不同权限的功能调用);
(3)当我们要扩展某个类的某个功能时,可以使用代理模式,在代理类中进行简单扩展(只针对简单扩展,可在引用委托类的语句之前与之后进行);
代理模式关键点------代理模式和装饰者模式差异:(体现在方法的实现中)
装饰者模式,装饰以后会添加新功能;
代理模式目的是对目标对象访问的控制和管理;
什么情况下用代理模式什么情况下用装饰模式呢?
那就得看情况了,如果是为了给对象增加功能,那就用装饰模式。比如一个Car类它的speed()方法中行驶速度是300m/s,那能不能实现500m/s的汽车对象呢?有装饰模式就可以实现。700m/s的呢?装饰两次就行了。不是定义两个装饰器类,而是定义一个装饰器能够增速200m/s,然后装饰两次。