中介者模式
定义
定义一个中介对象来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以独立地改变它们之间的交互。中介者模式又叫调停模式,它是迪米特法则的典型应用
结构
- 抽象中介者(Mediator)角色:它是中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法
- 具体中介者(ConcreteMediator)角色:实现中介者接口,定义一个 List 来管理同事对象,协调各个同事角色之间的交互关系,因此它依赖于同事角色
- 抽象同事类(Colleague)角色:定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能
- 具体同事类(Concrete Colleague)角色:是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互
实现
//Eureka就是使用中介者模式,将各个服务注册到Eureka服务器,各个服务之间的调用通过Eureka获取调用地址
public class MediatorPattern
{
public static void main(String[] args)
{
Mediator mediator = new ConcreteMediator();
Colleague colleague1 = new ConcreteColleague1("colleague1");
Colleague colleague2 = new ConcreteColleague2("colleague2");
mediator.register(c1);
mediator.register(c2);
colleague1.send("colleague2");
colleague2.send("colleague1");
}
}
//抽象中介者
abstract class Mediator
{
protected Map<String,Colleague> colleagues = new HashMap<String,Colleague>();
public abstract void register(Colleague colleague);
public abstract void relay(String name); //转发
}
//具体中介者
class ConcreteMediator extends Mediator
{
public void register(Colleague colleague)
{
if(!colleagues.containsKey(colleague.getName()))
{
colleagues.set(colleague.getName(),colleague);
colleague.setMedium(this);
}
}
public void relay(String name)
{
Colleague colleague = colleagues.get(name);
if(null != colleague){
colleague.receive();
}
}
}
//抽象同事类
abstract class Colleague
{
private String name;
protected Mediator mediator;
public Colleague(String name){
this.name = name;
}
public void setMedium(Mediator mediator)
{
this.mediator=mediator;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void send(String name)
{
System.out.println("具体同事"+ this.name +"发出请求。");
mediator.relay(name); //请中介者转发
}
public abstract void receive();
}
//具体同事类
class ConcreteColleague1 extends Colleague
{
public ConcreteColleague1(String name){
super(name);
}
public void receive()
{
System.out.println("具体同事类1收到请求。");
}
}
//具体同事类
class ConcreteColleague2 extends Colleague
{
public ConcreteColleague2(String name){
super(name);
}
public void receive()
{
System.out.println("具体同事类2收到请求。");
}
}
优点和缺点
优点
- 降低了对象之间的耦合性,使得对象易于独立地被复用
- 将对象间的一对多关联转变为一对一的关联,提高系统的灵活性,使得系统易于维护和扩展
缺点
- 当同事类太多时,中介者的职责将很大,它会变得复杂而庞大,以至于系统难以维护
应用场景
- 当对象之间存在复杂的网状结构关系而导致依赖关系混乱且难以复用时。
- 当想创建一个运行于多个类之间的对象,又不想生成新的子类时
扩展使用
//不定义中介者接口,把具体中介者对象实现成为单例。
//同事对象不持有中介者,而是在需要的时f矣直接获取中介者对象并调用
public class SimpleMediatorPattern
{
public static void main(String[] args)
{
SimpleColleague c1,c2;
c1=new SimpleConcreteColleague1();
c2=new SimpleConcreteColleague2();
c1.send();
System.out.println("-----------------");
c2.send();
}
}
//简单单例中介者
class SimpleMediator
{
private static SimpleMediator smd=new SimpleMediator();
private List<SimpleColleague> colleagues=new ArrayList<SimpleColleague>();
private SimpleMediator(){}
public static SimpleMediator getMedium()
{ return(smd); }
public void register(SimpleColleague colleague)
{
if(!colleagues.contains(colleague))
{
colleagues.add(colleague);
}
}
public void relay(SimpleColleague scl)
{
for(SimpleColleague ob:colleagues)
{
if(!ob.equals(scl))
{
((SimpleColleague)ob).receive();
}
}
}
}
//抽象同事类
interface SimpleColleague
{
void receive();
void send();
}
//具体同事类
class SimpleConcreteColleague1 implements SimpleColleague
{
SimpleConcreteColleague1(){
SimpleMediator smd=SimpleMediator.getMedium();
smd.register(this);
}
public void receive()
{ System.out.println("具体同事类1:收到请求。"); }
public void send()
{
SimpleMediator smd=SimpleMediator.getMedium();
System.out.println("具体同事类1:发出请求...");
smd.relay(this); //请中介者转发
}
}
//具体同事类
class SimpleConcreteColleague2 implements SimpleColleague
{
SimpleConcreteColleague2(){
SimpleMediator smd=SimpleMediator.getMedium();
smd.register(this);
}
public void receive()
{ System.out.println("具体同事类2:收到请求。"); }
public void send()
{
SimpleMediator smd=SimpleMediator.getMedium();
System.out.println("具体同事类2:发出请求...");
smd.relay(this); //请中介者转发
}
}