设计之禅——中介者模式
引言
在面向对象编程中,无可避免的是对象之间的引用,引用给我们带来便捷(对象的复用),但同时也会给类与类之间造成强依赖关系。在一对一的关系中,这看起来并不会造成什么不良的影响,但若是在一对多中,修改任意的一个对象,都会影响到其它调用者,形成强耦合。
中介者
如同上面的图,当对象之间形成网络结构之后,改变5号对象只会影响到4号对象,改变1号对象,其引用它的4、5、6号对象都需要作出相应的改变,而改变2号对象其它5个对象都需要作出改变,我们想要跟踪对象的引用是非常的困难的,因此我们需要将其解耦。 那要如何做呢? 不难发现,我们只需要将网络结构中的一对多的引用改造成为一对一的结构,那么不就非常简单了么。
像上面这样,引入一个中介者对象,所有对象之间的联系都必须通过中介者来处理,这样,所有对象也就只有一个对象与之关联,我们在修改任意的对象时也只需要修改中介者对象对应的逻辑即可,引用的跟踪也不再是难事了。这就是中介者模式的威力。
Coding
在现实生活中,我们可以看到很多中介者的例子,有时我们也会与其打交道,比如找房屋中介租房,下面就以这个例子来说明,首先是房东和租客,这里为了处理方便,使它们都继承自抽象的people类:
public class Person {
protected String name;
protected String message;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMessage() {
return this.name + "收到消息:" + this.message;
}
public void setMessage(String message) {
this.message = message;
}
}
public class Landlord extends Person {
public Landlord(String name) {
super(name);
}
}
public class Tenant extends Person {
public Tenant(String name) {
super(name);
}
}
然后是中介者类(考虑到以后的扩展,抽象出一个抽象的中介者,并持有contact方法,房东和租客则是通过中介者来取得联系)
public abstract class AbstractMediator {
public abstract void contact(String message, Person person);
}
public class HouseMediator extends AbstractMediator {
@Override
public void contact(String message, Person person) {
person.setMessage(message);
}
}
最后测试
public static void main(String[] args) {
AbstractMediator mediator = new HouseMediator();
Person landlord = new Landlord("房东");
mediator.contact("我要租房", landlord);
System.out.println(landlord.getMessage());
Tenant tenant = new Tenant("租客");
mediator.contact("一个月500", tenant);
System.out.println(tenant.getMessage());
}
打印如下结果:
房东收到消息:我要租房
租客收到消息:一个月500
像上面这样就实现了一个中介者模式,我们改动任意的对象(房东或是租客),受到影响的仅仅只有中介者。当然,这里只是为了说明中介者模式,例子本身简单,没有必要使用中介者模式,但不妨想想,对象一旦增多,并相互引用,这个模式带给我们的好处不言而喻。
总结
中介者模式可以帮助我们解除对象之间的耦合,但是在实际编码中并不是经常被使用。因为它会使得体系结构变得非常复杂,在使用该模式之前,我们首先应该想想是不是本身的设计是否存在问题。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- php 实现svg转化png格式的方法分析
- Python如何合并多个字典或映射
- 用Python 爬取猫眼电影数据分析《无名之辈》
- Python获取浏览器窗口句柄过程解析
- python如何支持并发方法详解
- thinkPHP+mysql+ajax实现的仿百度一下即时搜索效果详解
- php和C#的yield迭代器实现方法对比分析
- Python字符串函数strip()原理及用法详解
- python中取绝对值简单方法总结
- Linux中将txt导入到mysql的办法教程
- 深入了解NumPy 高级索引
- CentOS7设置jar应用程序开机启动的办法
- linux系统 java环境变量的配置办法
- 在Linux中怎么轻松删除源安装的软件包
- Linux中selinux基础配置教程详解