• 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,然后装饰两次。

  • 相关阅读:
    深入理解Java8中Stream的实现原理
    RocketMQ的顺序消费和事务消费
    Java 性能调优小技巧
    类加载机制基础
    十大经典排序算法
    分布式锁的几种常用实现方式
    python之接口开发
    python之urllib模块和requests模块
    python之time模块和hashlib模块
    python之os和sys模块的区别
  • 原文地址:https://www.cnblogs.com/mmzs/p/7674488.html
Copyright © 2020-2023  润新知