在没有使用代理模式的时候,使用者和被使用者耦合。
使用代理模式之后,使用者和代理耦合,代理和被使用者耦合。
为什么要解耦呢?通常是应为变化,需求变化导致最终的程序实现变化,如果耦合度高,出现变化时所需要修改的程序就多,如果进行解耦,那修改的程序就少(被解耦的部分已经不需要修改,因为和变化的地方没有直接的关系了)。
下面举个不太恰当的例子。
假设客户要开发一个游戏,刚开始,有猫和儿童两个类,儿童和猫玩,这两个类有了耦合。
public class 猫 { public void 叫() { System.out.println( "喵!" ); } } public class 儿童 { public static void main(String[] args) { 猫 c = new 猫(); c.叫(); } } |
之后,又慢慢地多了少年、青年、中年类,都和猫玩,这些类都和猫类有了耦合。
突然,有一天,客户说和猫玩没意思,要和狗玩。于是增加了狗类,修改了儿童、少年、青年、中年类。
public class 狗 { public void 叫() { System.out.println( "汪!" ); } } public class 儿童 { public static void main(String[] args) { 狗 c = new 狗 (); c.叫(); } } // 少年、青年、中年 也修改为和狗玩 |
过了一阵子,客户又发神经了,说和狗玩厌了,还是改成以前的和猫玩吧。于是又要把儿童、少年、青年、中年类都修改一遍。
这种改动实在是太烦了,于是就考虑把猫、狗和儿童、少年、青年、中年解耦,发明出一个接口:会叫的东西。猫、狗实现会叫的东西,儿童、少年、青年、中年和会叫的东西玩。
同时增加一个配置(文件配置、数据库配置、注册表配置,看实际情况使用哪种),指定现在使用猫还是狗,还要增加一个工厂去读取这个配置创建猫或狗。
public interface 会叫的东西 { public void 叫(); } public class 猫 implements 会叫的东西 { public void 叫() { System.out.println( "喵!" ); } } public class 狗 implements 会叫的东西 { public void 叫() { System.out.println( "汪!" ); } } public class 会叫的东西工厂 { public static 会叫的东西 造一个会叫的东西() throws Exception { // 首先在某个地方(如某个指定文件)配置猫还是狗,在这里读取配置 String 配置 = 读取配置(); if ( "猫" .equals(配置)) return new 猫(); else if ( "狗" .equals(配置)) return new 狗(); else throw new Exception( "未知的配置:" + 配置 + "。" ); } private static String 读取配置() { return null ; // 根据实际情况读取配置 } } public class 儿童 { public static void main(String[] args) throws Exception { 会叫的东西 c = 会叫的东西工厂.造一个会叫的东西(); c.叫(); } } // 少年、青年、中年 也修改为和会叫的东西玩 |
再往后,如果客户说和狗玩、和猫玩…就只需要修改配置,不再需要去修改儿童、少年、青年、中年类了。
如果客户说现在要和知了玩,那也只需要新增个知了类,同时修改配置和会叫的东西工厂就可以了。
代理模式比较特殊,目的主要是增加间接性,由代理隐藏一些复杂操作或做一些额外的特殊处理,不是为了隔离变化。