适配器模式,这个模式也很简单,你笔记本上的那个拖在外面的黑盒子就是个适配器,1般你在中国能用,在日本也能用,虽然两个国家的的电源电压不同,中国是 220V,日本是 110V,但是这个适配器能够把这些不同的电压转换为你需要的 36V 电压,保证你的笔记本能够正常运行,那我们在设计模式中引入这个适配器模式是否是也是这个意思呢?是的,1样的作用,两个不同接口,有不同的实现,但是某1天突然上帝命令你把 B 接口转换为 A 接口,怎样办?继承,能解决,但是比较傻,而且还背背了 OCP 原则,怎样办?好在我们还有适配器模式。
适配器的通用类图是这个模样滴:
Target 是1个类(接口) ,Adaptee 是1个接口,通过 Adapter 把 Adaptee 包装成 Target 的1个子类(实现类) ,注意了这里用了个名词包装(Wrapper) ,那其实这个模式也叫做包装模式(Wrapper),但是包装模式可不知1个,还包括了以后要讲的装潢模式。我来说个自己的1个经验,让大家可以更容易了解这个适配器模式,否则纯讲技术太枯燥了,技术也能够有文娱的嘛。
我在 2004 年的时候带了1个项目,做1个人力资源管理,该项目是我们总公司发起的项目,公司1共有 700 多号人,包括子公司,这个项目还是比较简单的,分为3大模块:人员信息管理,薪酬管理,职位管理,其中人员管理这块就用到了适配器模式,是怎样回事呢?当时开发时明确的指明:人员信息简管理的对象是所有员工的所有信息,然后我们就这样设计了1个类图:
还是比较简单的,有1个对象 UserInfo 存储用户的所有信息(实际系统上还有很多子类,不多说了),也就是BO(Business Object) ,这个 UserInfo 对象,在系统中很多地方使用,你可以查看自己的信息,也能够做修改,固然这个对象是有 setter 方法的,我们这里用不到就隐藏掉了。
这个项目是 04 年年底投产的,运行到 05 年年底还是比较安稳的,中间修修补补也很正常,05 年年底不知道是那股风吹的,很多公司开始使用借聘人员的方式招聘人员,我们公司也不例外,从1个人力资源公司借用了1大批的低技术、低工资的人员,分配到各个子公司,总共有将近 200 号人,然后就找我们部门老大谈判,说要增加1个功能借用人员管理,老大1看有钱赚呀,1拍大腿,做!
我带人过去1调研,不是这么简单,人力资源公司有1套自己的人员管理系统,我们公司需要把我们使用到的人员信息传输到我们的系统中,系统之间的传输使用 RMI(Remote Method Invocation,远程对象调用)的方式,但是有1个问题人力资源公司的人员对象和我们系统的对象不相同呀,他们的对象是这样的:
人员资源公司是把人的信息分为了3部份: 基本信息, 办公信息和个人家庭信息, 并且都放到了 HashMap中,比如人员的姓名放到 BaseInfo信息中,家庭地址放到 HomeInfo 中,这咱不好说他们系统设计的不好,那问题是咱的系统要和他们系统有交互,怎样办?使用适配器模式,类图以下:
大家可能会问,这两个对象都不在1个系统中,你如何使用呢?简单!RMI 已帮我们做了这件事情,只要有接口,就能够把远程的对象当做本地的对象使用,这个大家有时间可以去看1下 RMI 文档,不多说了。通过适配器,把 OuterUser 假装成我们系统中1个 IUserInfo 对象,这样,我们的系统基本不用修改甚么程序,所有的人员查询、调用跟本地1样样的,说的口干舌燥,那下边我们来看具体的代码实现:
首先看 IUserInfo.java 的代码:
然后看这个接口的实现类:
可能有人要问了,为何要把电话号码、手机号码都设置成 String 类型,而不是 int 类型,大家觉的呢?题外话,这个绝对应当是 String 类型,包括数据库也应当是 varchar 类型的,手机号码有小灵通带区号的,比如 02100001,这个你用数字怎样表示?有些人要在手机号码前加上 0086 后再保存,比如我们公司的印度阿3就是这样,喜欢在手机号码前 0086保存下来,呵呵,我是想到啥就说啥,
下一篇 R语言的数据结构