问题引入
代理模式需要解决的问题其实很简单,有些代码是第三方库,我们修改不能,因此需要一个代理模式在此基础上进行横向增强。
或者类比生活中的例子,买房子要找中介,上课没来找个好兄弟帮你代点名,等等。
此部分仅仅从很简单浅显的角度来进行理解静态代理的设计模式,作为一个 quick start ,后续会深入理解动态代理等部分。
思路分析
主要是有三个成员,这里我们以上课的时候某同学没来,找好兄弟代点名为例作为背景
抽象接口
可以简单理解为表示的是一个能力,比如我们代理同学上课点名,这个能力就是喊到
1 2 3
| public interface CheckAttandance(){ void sayAttand(); }
|
实现类
这个实现类在这个背景中就是指:这个应该来的同学,它实现了喊到
的这个接口,可以喊到
了
1 2 3 4 5 6
| public class ConcreteStudent implements CheckAttandance{ @Override public void sayAttand(){ System.out.println("老师我到了"); } }
|
代理类
这个情景中指的是我们代点名的同学,在代理模式中他叫做代理对象
代理对象一般需要显式声明被代理的对象,作为一个内部成员
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class Proxy implements CheckAttandance{ static ConcreteStudent student; private void minusVoice(){ System.out.println("使用消音器"); } @Override public void sayAttand(){ minusVoice(); if(student==null){ student = new ConcreteStudent(); } student.sayAttand(); } }
|
测试
1 2 3 4 5 6
| public class ProxyDemo { public static void main(String[] args) { Proxy proxy = new Proxy(); proxy.sayAttand(); } }
|
代码实现
上述的思路分析中其实已经可以看出一些代理模式的影子了
下面给出代理模式另一个常用的场景————代理某个对象实现延迟初始化,代码抽象出一些比较通用可被替换的操作,希望能活学活用
某个接口/抽象类
1 2 3 4
| abstract class Subject { public abstract void doSomeWork(); }
|
某一个具体实现类
1 2 3 4 5 6 7 8
| class ConcreteSubject extends Subject { @Override public void doSomeWork() { System.out.println("doSomeWork() inside ConcreteSubject is invoked."); } }
|
代理类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| class Proxy extends Subject { static Subject cs; @Override public void doSomeWork() { System.out.println("Proxy call happening now..."); if (cs == null) { cs = new ConcreteSubject(); } cs.doSomeWork(); } }
|
测试调用
1 2 3 4 5 6
| public class ProxyPatternExample { public static void main(String[] args) { Proxy proxy = new Proxy(); proxy.doSomeWork(); } }
|