第十八讲:中介者模式
类之间的交互行为被统一放在Mediator的对象中.
古代的媒婆,婚姻中介.
类之间存在交互行为.Man里面调用了Woman的一个方法.Woman里面调用Man的一个方法.有人会说它们都是一个公共方法,是Person里面的.这里比较特殊.Man调用了Woman,Woman同样也调用了Man.Person是Woman的实例,调用了Woman的方法.Woman调用了Man的方法.
张三找小芳谈心和到小芳家里看一下获取小芳的条件从程序的角度上看这些都是调用了小芳的方法.调用了Woman的方法.使得两个类之间的耦合度非常高.如果Woman里面的方法改变了Man也必须修改.因为你们之间存在交互.两个类紧密地联系在一起.
Mediator:中介者类的抽象父类.Mediator
concreteMediator:具体的中介者类.
colleague:关联类的抽象父类.Person
concreteColleague:具体的关联类.Man/Woman
黑色箭头表示具体的中介者类持有具体的关联类的引用.中介者类持有两个关联类的引用.媒婆同时有男的和女的信息.中介公司必须有男性和女性的信息.colleague关联类的抽象父类持有中介者的抽象父类的引用.
小张和小芳去找中介结构,首先他们会在中介公司注册.同时呢他们会拿中介结构的本本,介绍他们中介结构有哪些人物的信息,所以他们持有了中介机构的引用.
中介机构保存了两个人的信息,而人呢又保存了中介机构的引用.
Person关联类持有中介者的引用.
//完成了婚介机构持有了男和女的引用,并且Woman和Man的getPartner()方法都放到了中介者里面了.
//因为不用自己去找了,婚姻机构帮我去找.
//因为Mediator只关注将你的对象设置上,你自己的信息你自己设置.
//Man还是要去找对象,不需要自己去找,因为你持有中介公司的引用,你可以打电话去问中介结构.
//为什么要持有中介公司的引用,这里也是一个原因,第一可以设置它的这个属性,将自己注册上.
//第二可以调用中介公司获得对象的方法.
//持有中介公司的引用,第一可以将自己注册到里面去,第二是为了调用中介公司里面的getPartner()方法.
//中介者持有具体的关联类的引用来作为它的具体实现.同时关联类的抽象父类也持有中介者的引用.大家不要搞混了,你持有它的引用,它也持有你的引用,这是没有问题的.
//中介者持有具体的关联类的引用是为了比较两者之间的条件,而具体关联类的抽象父类持有中介者的引用和具体关联类持有中介者的引用是为了将自己设置上/注册上并且调用中介者里面的getPartner()方法.
package com.ibeifeng.ex1; public class MainClass { //类之间存在交互行为.Man调用了Woman,Woman同样也调用了Man. public static void main(String[] args) { Person zhangsan = new Man("张三",5); Person lisi = new Man("李四",6); Person xiaofang = new Woman("小芳",6); zhangsan.getPartner(xiaofang); lisi.getPartner(xiaofang); zhangsan.getPartner(lisi); } }
package com.ibeifeng.ex1; public class Man extends Person{ public Man(String name, int condition) { super(name, condition); // TODO Auto-generated constructor stub } @Override public void getPartner(Person person) {//找到的对象到底合不合你 // TODO Auto-generated method stub if(person instanceof Man){ System.out.println("汗,我不是同性恋!!!!"); }else { if(this.getCondition()==person.getCondition()){//门当会对 System.out.println(this.getName()+ "和" +person.getName() +"绝配"); }else{ System.out.println(this.getName() + "和" + person.getName() + "不相配"); } } } }
package com.ibeifeng.ex1; public class Woman extends Person { public Woman(String name, int condition) { super(name, condition); // TODO Auto-generated constructor stub } @Override public void getPartner(Person person) { // TODO Auto-generated method stub if(person instanceof Woman){ System.out.println("汗,我不是同性恋!!!!"); }else { if(this.getCondition()==person.getCondition()){//门当会对 System.out.println(this.getName()+ "和" +person.getName() +"绝配"); }else{ System.out.println(this.getName() + "和" + person.getName() + "不相配"); } } } }
package com.ibeifeng.ex1; //找对象. public abstract class Person { private String name; private int condition; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getCondition() { return condition; } public void setCondition(int condition) { this.condition = condition; } public Person(String name, int condition) { super(); this.name = name; this.condition = condition; } //还没有中介者,自己去找对象 public abstract void getPartner(Person person);//找伴侣,找到另一半. }
使用中介者模式的代码
package com.ibeifeng.ex2; public class MainClass { public static void main(String[] args) { Mediator mediator = new Mediator(); Person zhangsan = new Man("张三",7,mediator); Person lisi = new Man("李四",7,mediator); Person xiaofang = new Woman("小芳",7,mediator); //zhangsan.getPartner(xiaofang); zhangsan.getPartner(lisi);//持有中介结构的引用,第一为了将自己设置上. xiaofang.getPartner(lisi); } }
package com.ibeifeng.ex2; public class Man extends Person{ /* public Man(String name, int condition) { super(name, condition); // TODO Auto-generated constructor stub } */ public Man(String name, int condition, Mediator mediator) { super(name, condition, mediator); // TODO Auto-generated constructor stub } @Override public void getPartner(Person person) {//找到的对象到底合不合你 // TODO Auto-generated method stub this.getMediator().setMan(this);//因为Mediator只关注将你的对象设置上,你自己的信息你自己设置. this.getMediator().getPartner(person);;//Man还是要去找对象,不需要自己去找,因为你持有中介公司的引用, //你可以打电话去问中介结构. //为什么要持有中介公司的引用,这里也是一个原因,第一可以设置它的这个属性,将自己注册上. //第二可以调用中介公司获得对象的方法. //持有中介公司的引用,第一可以将自己注册到里面去,第二是为了调用中介公司里面的getPartner()方法. } }
package com.ibeifeng.ex2; public class Woman extends Person { /* public Woman(String name, int condition) { super(name, condition); // TODO Auto-generated constructor stub }*/ public Woman(String name, int condition, Mediator mediator) { super(name, condition, mediator); // TODO Auto-generated constructor stub } @Override public void getPartner(Person person) { // TODO Auto-generated method stub this.getMediator().setWoman(this);//在婚姻结构注册. this.getMediator().getPartner(person);//为什么要持有中介公司的引用,因为随时要调用它的 //getPartner()方法. } }
package com.ibeifeng.ex2; import com.ibeifeng.ex2.Person; import com.ibeifeng.ex2.Woman; //完成了婚介机构持有了男和女的引用,并且Woman和Man的getPartner()方法都放到了中介者里面了. //因为不用自己去找了,婚姻机构帮我去找. public class Mediator { private Man man; private Woman woman;//中介者持有具体的关联类的引用来作为它的具体实现. /* public Man getMan() { return man; }*/ public void setMan(Man man) { this.man = man; } /* public Woman getWoman() { return woman; }*/ public void setWoman(Woman woman) { this.woman = woman; } public void getPartner(Person person) { // TODO Auto-generated method stub //将对象的设置上. if(person instanceof Man){ this.setMan((Man)person);//把Man的实例添加上. }else { this.setWoman((Woman)person); } //判断条件 if(man==null || woman==null){ System.out.println("汗,我不是同性恋!"); }else{ if(man.getCondition()==woman.getCondition()){ System.out.println(man.getName()+ "和" +woman.getName() +"绝配"); }else{ System.out.println(man.getName() + "和" + woman.getName() + "不相配"); } } } }
package com.ibeifeng.ex2; //找对象. public abstract class Person { private String name; private int condition; private Mediator mediator;//同时关联类的抽象父类也持有中介者的引用. //大家不要搞混了,你持有它的引用,它也持有你的引用,这是没有问题的. //中介者持有具体的关联类的引用是为了比较两者之间的条件,而具体关联类的抽象父类持有中介者的引用和具体关联类持有中介者的引用是为了将自己设置上/注册上并且调用中介者里面的getPartner()方法. public String getName() { return name; } public void setName(String name) { this.name = name; } public int getCondition() { return condition; } public void setCondition(int condition) { this.condition = condition; } /* public Person(String name, int condition) { super(); this.name = name; this.condition = condition; }*/ //还没有中介者,自己去找对象 public abstract void getPartner(Person person);//找伴侣,找到另一半. public Person(String name, int condition, Mediator mediator) { super(); this.name = name; this.condition = condition; this.mediator = mediator; } public Mediator getMediator() { return mediator; } public void setMediator(Mediator mediator) { this.mediator = mediator; } }
Man和Woman没有交互动作了,交互动作放到中介者里面去了.如果有三四个Man或者是Woman,关联类之间的关系会非常复杂.可以把关联类之间的关联关系都放到Mediator里面,把类之间的多对多关系转换成Mediator和多个关联类之间的一对多关系.当一个类修改时,不对其他关联类产生影响,因为它们相互之间的操作放到了Mediator里面.即使有修改,也是放到了Mediator控制类里面.有利于提高类的重用性,例如Man,就算Man类内部修改了,也不影响其被其他类调用.