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]