代理模式(结构型)

来源:互联网 发布:下载办公软件最新版 编辑:程序博客网 时间:2024/05/16 23:45

代理模式:

代理模式给某一个对象提供一个代理对象,并由代理对象控制对源对象的引用。代理就是一个人或一个机构代表另一个人或者一个机构采取行动。某些情况下,客户不想或者不能够直接引用一个对象,代理对象可以在客户和目标对象直接起到中介的作用。客户端分辨不出代理主题对象与真实主题对象。代理模式可以并不知道真正的被代理对象,而仅仅持有一个被代理对象的接口,这时候代理对象不能够创建被代理对象,被代理对象必须有系统的其他角色代为创建并传入。


代理结构图:


动态代理结构图:


需求:

1.静态代理描述

西门庆(ˇˍˇ) 想~找潘金莲么么哒,可惜怕被武松打了,就通过王婆来做代理,介绍潘金连给西门庆。后来西门庆又来找王婆的,王婆又作为代理找来了贾氏跟西门庆么么哒。

---------------------------------------------------------


-------------------------

西门庆(client)

-----------------------------

public class Ximenqing {public static void main(String[] args) {JFrame jfram=new JFrame("水浒传");JTextArea jTextArea=new JTextArea();String str="*******西门庆通过王婆找潘金莲********";Allwomen panjiglian=new Panjinglian();WangPo wangpo=new WangPo(panjiglian);wangpo.show();wangpo.kiss();jTextArea.append(str+"\n");jTextArea.append(wangpo.show()+"\n");jTextArea.append(wangpo.kiss()+"\n");String str2="*******西门庆通过王婆找贾氏********";Allwomen jiashi=new Jiashi();WangPo wangpo1=new WangPo(jiashi);jTextArea.append(str2+"\n");jTextArea.append(wangpo1.show()+"\n");jTextArea.append(wangpo1.kiss()+"\n");jfram.setSize(new Dimension(500, 300));jfram.setPreferredSize(new Dimension(500, 300));jfram.add(jTextArea);jTextArea.setBackground(new Color(125, 175, 255));jTextArea.setFont(new Font("楷体", 0, 20));jfram.setDefaultCloseOperation(1);jfram.setVisible(true);}}

----------------------------------

王婆(proxy)

-----------------------------------

public class WangPo implements Allwomen{private Allwomen panjinglian=null;public WangPo(Allwomen allwomen){this.panjinglian=allwomen;}@Overridepublic String show() {// TODO Auto-generated method stubreturn panjinglian.show();}@Overridepublic String kiss() {// TODO Auto-generated method stubreturn panjinglian.kiss();}}

--------------------------------------

贾氏和潘金连(realsubject)

---------------------------------------

public class Jiashi implements Allwomen{@Overridepublic String show() {// TODO Auto-generated method stubreturn "贾氏学潘金莲对西门庆抛媚眼";}@Overridepublic String kiss() {// TODO Auto-generated method stubreturn "贾氏学潘金跟西门庆连亲亲";}}public class Panjinglian implements Allwomen{@Overridepublic String show() {// TODO Auto-generated method stubreturn "潘金莲对西门庆抛媚眼";}@Overridepublic String kiss() {// TODO Auto-generated method stubreturn "潘金莲跟西门庆亲亲";}}

------------------------------------

女人(subject)

------------------------------------

public interface Allwomen {    /**     * 抛媚眼      */public String show();/*** 亲亲*/public String kiss();}

---------------------------------------

结果:


-----------------------------------------------------------------------------------------------------------------------------------



动态代理:


----------------------------------------------------------

具体主题

-------------------------------------------------------------

public class GamePlayer implements IGamePlay{@Overridepublic void login() {// TODO Auto-generated method stubSystem.out.println("玩家登陆");}}

---------------------------------------------------------

代理

--------------------------------------------------

public class GamePlayInvocationHandler implements InvocationHandler{private Object proxyObject;public GamePlayInvocationHandler(Object proxyObject){this.proxyObject=proxyObject;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {Object obj=null;// TODO Auto-generated method stubif("login".equals(method.getName())){System.out.println("方法执行前");obj=method.invoke(this.proxyObject, args);System.out.println("方法执行后");}return obj;}}

---------------------------------------------------

主题

----------------------------------------------------

public interface IGamePlay {public void login();}

---------------------------------------------------

客户

-----------------------------------------------------

public class Main {public static void main(String[] args) {IGamePlay gamePlay=new GamePlayer();   ClassLoader cls=gamePlay.getClass().getClassLoader();   Class<?>[]  clsa=gamePlay.getClass().getInterfaces();GamePlayInvocationHandler gamePlayInvocationHandler=new GamePlayInvocationHandler(gamePlay);IGamePlay proxy= (IGamePlay) Proxy.newProxyInstance(cls, clsa, gamePlayInvocationHandler);proxy.login();}}

------------------------------------------------------

-------------------------------------------------------------

远程代理

---------------------------------------------------------------


解释一下,Stub是“桩”也有人称之为“存根”,代表了Server对象

Skeleton是“骨架”(不知道为什么叫“桩”和“骨架”,当然,也没必要知道),代表了Client

Stub明明在客户那边,为什么不是客户的代理而是服务的代理?因为客户是要与服务器交互,现在服务在远程JVM中,无法交互,所以用Stub来代表Server,调用Stub就等同于调用Server(内部通信机制对Client透明,对Client来说,调用Stub和直接调用Server没什么区别,而这正是代理模式的优点之一)

具体流程是这样的:

  1. Client向Stub发送方法调用请求(Client以为Stub就是Server)
  2. Stub接到请求,通过Socket与服务端的Skeleton通信,把调用请求传递给Skeleton
  3. Skeleton接到请求,调用本地Server(听起来有点奇怪,这里Server相当于Service)
  4. Server作出对应动作,把结果返回给调用者Skeleton
  5. Skeleton接到结果之后通过Socket发送给Stub
  6. Stub把结果传递给Client
-----------------------------------------------------------------------------------------------


-------------------------------------------

客户

-----------------------------------------

/**  * @author Administrator * 西门庆(客户端) */public class Ximenqing {public static void main(String[] args) {try {WangPo wanPo=new WangPo();Thread.sleep(2000);Allwomen jiashi=(Allwomen) Naming.lookup("//172.20.148.1:8088/jiashi");System.out.println(jiashi.show());System.out.println(jiashi.kiss());System.out.println("---------------");Allwomen panjinglian=(Allwomen) Naming.lookup("//172.20.148.1:8088/panjinglian");System.out.println(panjinglian.show());System.out.println(panjinglian.kiss());} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();} }}

-----------------------------------------------

真实的主题

----------------------------------------------

public class Jiashi extends UnicastRemoteObject implements Allwomen{public Jiashi() throws RemoteException {super();// TODO Auto-generated constructor stub}/*** */private static final long serialVersionUID = 1L;@Overridepublic String show() throws RemoteException {// TODO Auto-generated method stubreturn "潘金连抛媚眼";}@Overridepublic String kiss() throws RemoteException {// TODO Auto-generated method stubreturn "潘金连亲亲";}}/** * @author Administrator * 继承UnicastRemoteObject 自动实现stub类 有了"桩" */public class Panjinglian extends UnicastRemoteObject  implements Allwomen{public Panjinglian() throws RemoteException {super();// TODO Auto-generated constructor stub}private static final long serialVersionUID = 1L;@Overridepublic String show() throws RemoteException {// TODO Auto-generated method stubreturn "贾氏学潘金连抛眉眼";}@Overridepublic String kiss() throws RemoteException {// TODO Auto-generated method stubreturn "贾氏学潘金连亲亲";}}

----------------------------------------------

远程服务

-------------------------------------------------

-----------------------------------------------

public interface Allwomen extends Remote{    /**     * 抛媚眼      */public String show() throws RemoteException;/*** 亲亲*/public String kiss() throws RemoteException;}

-------------------------------------------------

服务

---------------------------------------------------

/** * 王婆联系潘金连跟贾氏,远程服务器 * @author Administrator */public class WangPo{   public WangPo(){   new Thread(new Runnable() {@Overridepublic void run() {//启动rmi服务定义端口try {//LocateRegistry.createRegistry(8080);Allwomen panjinlian=new Panjinglian();Allwomen jiashi= new Jiashi();System.out.println("王婆收注册费");Naming.bind("rmi://172.20.148.1:8088/panjinglian",panjinlian);Naming.bind("rmi://172.20.148.1:8088/jiashi",jiashi);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}).start();  }}

---------------------------------------------------

0 0