jiangm520 发表于 2013-2-3 11:23:13

Design Pattern: Proxy 模式

来看看实现代理的两种方式:Static Proxy与Dynamic Proxy。严格来说这是属于模式的实现方式,不过藉由实例可以更了解Proxy模式的应用。

先来看个例子,这个例子是记录(log)动作,程式中很常需要为某些动作或事件作下记录,以便在事后检视或是作为除错时的资讯,一个最简单的例子如下:

[*]HelloSpeaker.java
import java.util.logging.*; public class HelloSpeaker {   private Logger logger =                Logger.getLogger(this.getClass().getName());   public void hello(String name) {         logger.log(Level.INFO, "hello method starts....");      System.out.println("Hello, " + name);         logger.log(Level.INFO, "hello method ends....");   } }
HelloSpeaker在执行hello()方法时,您希望能记录该方法已经执行及结束,最简单的作法就是如上在执行的前后加上记录动作,然而 Logger介入了HelloSpeaker中,记录这个动作并不属于HelloSpeaker,这使得HelloSpeaker增加了非业务上需要的逻辑在当中。

想想如果程式中这种记录的动作到处都有需求,上面这种写法势必造成必须复制记录动作的程式码,使得维护记录动作的困难度加大。如果不只有记录动作,有一些非物件本身职责的相关动作也混入了物件之中(例如权限检查、事务管理等等),会使得物件的负担更形加重,甚至混淆了物件的职责,物件本身的职责所占的程式码,或许远小于这些与物件职责不相关动作的程式码。

怎么办,用下面的方法或许好一些,先定义一个介面,然后实作该介面:

[*]IHello.java
public interface IHello {   public void hello(String name); }  

[*]HelloSpeaker.java
public class HelloSpeaker implements IHello {   public void hello(String name) {         System.out.println("Hello, " + name);   } }
接下来实作一个代理物件HelloProxy:

[*]HelloProxy.java
import java.util.logging.*; public class HelloProxy implements IHello {   private Logger logger =               Logger.getLogger(this.getClass().getName());   private IHello helloObject;   public HelloProxy(IHello helloObject) {         this.helloObject = helloObject;   }   public void hello(String name) {         logger.log(Level.INFO, "hello method starts....");         helloObject.hello(name);         logger.log(Level.INFO, "hello method ends....");   } }
执行时可以如此:
<div style="margin-left: 40px;">IHello helloProxy = new HelloProxy(new HelloSpeaker());
helloProxy.hello("Justin");
页: [1]
查看完整版本: Design Pattern: Proxy 模式