欢迎来到我的博客小站。  交流请加我微信好友: studyjava。  也欢迎关注公众号:Java学习之道 Fork me on GitHub

23种设计模式之五(代理模式)

代理模式:(为一个对象提供一个替身,以控制对这个对象的访问)

 被代理的对象可以是远程对象、创建开销大的对象或需要安全控制的对象;代理模式有很多变体,都是为了控制与管理对象访问。

代理模式包含如下角色:

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 }
State
 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 }
CandyMachineRemote

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 }
OnReadyState
 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 }
HasCoin
 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 }
SoldState
 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 }
SoldOutState
 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 }
WinnerState
 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 }
CandyMachine

不使用代理:

 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 }
Monitor
 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 }
MainTest

 

下面介绍一种代理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 }
MyRemote
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());
        } 
        
        
    }
}
MyRemoteImpl
 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 }
MyRemoteClient

 

接下来使用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 }
CandyMachineRemote
 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 }
Monitor
 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 }
RemoteMainTest
 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 }
MainTest

  

几种常见的代理模式介绍:

虚拟代理

  虚拟代理为创建开销大的对象提供代理服务。 真正的对象在创建前和创建中时,由虚拟代理来扮演替身。

  似乎很神秘,其实很简单 如: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 }
PersonBean
 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 }
PersonBeanImpl
 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 }
NonOwnerInvocationHandler
 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 }
OwnerInvocationHandler
 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 }
MatchService
 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 }
MainTest

 保护代理:

  当我们想要隐藏某个类时,可以为其提供代理类;

  类似房屋中介,相亲平台,代理律师;

1  public interface ZiRanRen {
2      void Quanli();
3  }
ZiRanRen
 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  }
Consigner
1  public class Lawyer implements ZiRanRen {
2      @Override
3      public void Quanli() {
4          new Consigner().Quanli();
5      }
6  }
Lawyer
1  public class Clienter {
2      public static void main(String[] args) {
3          ZiRanRen lawyer = new Lawyer();
4          lawyer.Quanli();
5      }
6  }
test

  可以看出,我们想对外开放某些功能,就可以将这些功能在代理类中被引用;如此一来,屏蔽了我们不想外露的功能,只将我们想开放的功能开放出来。亦即委托类中其实是可以有很多方法的,很多功能的,我们可以酌情对外开放,代理类犹如一道大门,将委托类与外部调用者隔绝开来,只将部分功能赋予这个大门,来代替委托类行使这个功能,哪怕最终还是要牵扯到自身(因为最终还是要调用委托类的对应方法实现)。

几种变体:

  防火墙代理

  缓存代理

  智能引用代理

  同步代理

  写入时复制代理

 

优点:

(1)代理类与委托类(被代理类)都实现了同一个接口,可实现灵活多变;继承式的实现方式则不够灵活;

(2)在委托类中实现功能,在代理类的方法中中引用委托类的同名方法;

(3)外部类调用委托类某个方法时,直接以接口指向代理类的实例,这正是代理的意义所在:屏蔽。

缺点:

 代理模式虽然实现了调用者与委托类之间的强耦合,但是却增加了代理类与委托类之间的强耦合(在代理类中显式调用委托类的方法),而且增加代理类之后明显会增加处理时间,拖慢处理时间。

 

欢迎加群一起交流:603654340

应用场景:

(1)当我们想要隐藏某个类时,可以为其提供代理类;

(2)当一个类需要对不同的调用者提供不同的调用权限时,可以使用代理类来实现(代理类不一定只有一个,我们可以建立多个代理类来实现,也可以在一个代理类中金进行权限判断来进行不同权限的功能调用);

(3)当我们要扩展某个类的某个功能时,可以使用代理模式,在代理类中进行简单扩展(只针对简单扩展,可在引用委托类的语句之前与之后进行);

 

 

代理模式关键点------代理模式和装饰者模式差异:(体现在方法的实现中)

装饰者模式,装饰以后会添加新功能;

代理模式目的是对目标对象访问的控制和管理

 

什么情况下用代理模式什么情况下用装饰模式呢?

那就得看情况了,如果是为了给对象增加功能,那就用装饰模式。比如一个Car类它的speed()方法中行驶速度是300m/s,那能不能实现500m/s的汽车对象呢?有装饰模式就可以实现。700m/s的呢?装饰两次就行了。不是定义两个装饰器类,而是定义一个装饰器能够增速200m/s,然后装饰两次。

posted @ 2017-10-29 13:42  淼淼之森  阅读(778)  评论(0编辑  收藏  举报
  👉转载请注明出处和署名