程序员该如何管理后宫:皇上选妃(代理模式)
2016-11-10 本文已影响178人
2453cf172ab4
0x00 前言
长这么大,朕从来没有听说哪个皇帝只有一个媳妇的,但是作为一名圣明与仁爱并存的帝王,朕只有yyj这个光杆皇后,因此朕要纳妃!
先给自己发一个呵呵!以上想法纯属扯淡!朕是绝对不会乱纳妃的,但是帝王毕竟是帝王,有时候装装样子还是要有的。
自己的媳妇当然是自己挑啦,不然看着不顺眼咋办,因此朕决定,要开启纳妃之路。朕要三下江南,选尽世间美貌之女子,尽收帐下!
先上个流程图压压惊:

方案是有了,但是每次选妃都要朕亲自出行,一是劳民伤财,朕于心不忍;二是这样做着实不太像样子。
朕仔细思考一番,朕既然有此困惑,其他的朝代的皇帝是不是也有,难不成每个皇帝选妃都要自己跑一圈不成?那不被史官骂死了?这就可以用到代理模式!
0x01 皇上选妃
皇上爱玩,出去选个妃什么的还能逛一圈江南。下面就先看一下朕是怎么选妃的。

我们需要一个GirlSearcher接口,里面有三个方法:travel,search,get。分别代表:出行江南!寻得一美人!收入帐下!
然后EmperorGirlSearcher实现了GirlSearcher接口,表示的是皇上。
Scene是场景类,里面描述了皇上选妃的流程。
1. 代码清单 GirlSearcher接口
public interface GirlSearcher {
public void travel();
public void search();
public void get();
}
2. 代码清单 EmperorGirlSearcher类
public class EmperorGirlSearcher implements GirlSearcher{
private static EmperorGirlSearcher emperorGirlSearcher = new EmperorGirlSearcher();
private EmperorGirlSearcher(){}
public static EmperorGirlSearcher getInstance() {
return emperorGirlSearcher;
}
@Override
public void travel() {
System.out.println("出行江南!");
}
@Override
public void search() {
System.out.println("寻得一美人!");
}
@Override
public void get() {
System.out.println("收入帐下!");
}
}
3. 代码清单 Scene类
public class Scene {
public static void main(String[] args) {
GirlSearcher emperor = EmperorGirlSearcher.getInstance();
//皇上亲自出发!
//第一次选妃
emperor.travel();
emperor.search();
emperor.get();
//第二次选妃
emperor.travel();
emperor.search();
emperor.get();
}
}
场景类里面描述了朕两次选妃的流程,下面看一下运行结果。
出行江南!
寻得一美人!
收入帐下!
出行江南!
寻得一美人!
收入帐下!
0x02 太监代选
作为一代明君,自己当然不能这么不像话,而且也累。因此就需要有人来代朕出行。这就是代理模式,朕选择一个小太监去江南晃悠一圈。

GirlSearcher接口和EmperorGirlSearcher不变,我们新加一个EunuchProxyGirlSearcher太监类。然后修改一下场景类。
1. 代码清单 EunuchProxyGirlSearcher类
public class EunuchProxyGirlSearcher implements GirlSearcher {
private GirlSearcher girlSearcher = null;
public EunuchProxyGirlSearcher(GirlSearcher girlSearcher) {
this.girlSearcher = girlSearcher;
}
@Override
public void travel() {
this.girlSearcher.travel();
}
@Override
public void search() {
this.girlSearcher.search();
}
@Override
public void get() {
this.girlSearcher.get();
}
}
2. 代码清单 ProxyScene场景类
可以看出,在新的场景类中,是太监代替朕出行了。运行结果和之前差不多。
public class ProxyScene {
public static void main(String[] args) {
GirlSearcher emperor = EmperorGirlSearcher.getInstance();
GirlSearcher eunuch = new EunuchProxyGirlSearcher(emperor);
//由小太监替皇上出行
//第一次选妃
eunuch.travel();
eunuch.search();
eunuch.get();
//第二次选妃
eunuch.travel();
eunuch.search();
eunuch.get();
}
}
0x03 代理模式
1. 代理模式的应用场合
代理模式有多种应用场合,如下所述:
- 远程代理,也就是为一个对象在不同的地址空间提供局部代表,这样可以隐藏一个对象存在于不同地址空间的事实。比如说 WebService,当我们在应用程序的项目中加入一个 Web 引用,引用一个 WebService,此时会在项目中声称一个 WebReference 的文件夹和一些文件,这个就是起代理作用的,这样可以让那个客户端程序调用代理解决远程访问的问题;
- 虚拟代理,是根据需要创建开销很大的对象,通过它来存放实例化需要很长时间的真实对象。这样就可以达到性能的最优化,比如打开一个网页,这个网页里面包含了大量的文字和图片,但我们可以很快看到文字,但是图片却是一张一张地下载后才能看到,那些未打开的图片框,就是通过虚拟代里来替换了真实的图片,此时代理存储了真实图片的路径和尺寸;
- 安全代理,用来控制真实对象访问时的权限。一般用于对象应该有不同的访问权限的时候;
- 指针引用,是指当调用真实的对象时,代理处理另外一些事。比如计算真实对象的引用次数,这样当该对象没有引用时,可以自动释放它,或当第一次引用一个持久对象时,将它装入内存,或是在访问一个实际对象前,检查是否已经释放它,以确保其他对象不能改变它。这些都是通过代理在访问一个对象时附加一些内务处理;
- 延迟加载,用代理模式实现延迟加载的一个经典应用就在 Hibernate 框架里面。当 Hibernate 加载实体 bean 时,并不会一次性将数据库所有的数据都装载。默认情况下,它会采取延迟加载的机制,以提高系统的性能。Hibernate 中的延迟加载主要分为属性的延迟加载和关联表的延时加载两类。实现原理是使用代理拦截原有的 getter 方法,在真正使用对象数据时才去数据库或者其他第三方组件加载实际的数据,从而提升系统性能。