第十九章行为型模式—中介者模式


行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象无法单独完成的任务,它涉及算法与对象间职责的分配。行为型模式分为类行为模式和对象行为模式:

  • 类行为模式:采用继承机制来在类间分派行为

  • 对象行为模式:采用组合或聚合在对象间分配行为

由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。

行为型模式分为:

  • 模板方法模式
  • 策略模式
  • 命令模式
  • 职责链模式
  • 状态模式
  • 观察者模式
  • 中介者模式
  • 迭代器模式
  • 访问者模式
  • 备忘录模式
  • 解释器模式

以上 11 种行为型模式,除了模板方法模式解释器模式是类行为型模式,其他的全部属于对象行为型模式。

中介者模式

中介者模式:又叫调停模式,是一种行为设计模式,能让你减少对象之间混乱无序的依赖关系。该模式会限制对象之间的直接交互,迫使它们通过一个中介者对象进行合作

解决的问题

image-20230524203453742

  • 我们的飞机想在机场进行降落,但是我们降落场每次只能降落一架飞机,需要飞机之间相互协商,如果我们采用飞行员之间相互沟通,这样的沟通方式是非常危险的,可能会导致飞机相撞事故
  • 但是如果我们引入了空管员这个中介者角色,来协调各个飞机来在这个降落场进行降落,维系各个飞机,而各个飞机不需要直接交互
  • 将网状结构变成了星状结构

结构

  • Mediator:抽象中介者角色,它是中介者的接口,提供了同事对象注册与转发同事对象信息的抽象方法。

  • ConcreteMediator:具体中介者角色,实现中介者接口,定义一个 List 来管理同事对象,协调各个同事角色之间的交互关系,因此它依赖于同事角色。

  • Colleague:抽象同事类角色,定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。

  • Concrete Colleague:具体同事类角色,是抽象同事类的实现者,当需要与其他同事对象交互时,由中介者对象负责后续的交互。

实例

现在租房基本都是通过房屋中介,房主将房屋托管给房屋中介,而租房者从房屋中介获取房屋信息。房屋中介充当租房者与房屋所有者之间的中介者。

在这里插入图片描述

抽象中介者角色

public abstract class Mediator {
    
    
    public abstract void trade(String message, Person person);
}

抽象同事类

@Data
@AllArgsConstructor
public abstract class Person {
    
    

    protected String name;
    protected Mediator mediator;
    private int type;  //1表示房主 0表示租客
    private int price; //表示当前期望的金额
    public void getMessage(String message) {
    
    
        System.out.println( name + "获取到的信息是:" + message);
    }
}

**具体同事类:**房主、房客

public class HouseOwner extends Person{
    
    
    public HouseOwner(String name, Mediator mediator, int type, int price) {
    
    
        super(name, mediator, type, price);
    }

    //和中介进行联系进行交易
    public void contact(String message){
    
    
        mediator.trade(message,this);
    }
}
public class Tenant extends Person {
    
    
    public Tenant(String name, Mediator mediator, int type, int price) {
    
    
        super(name, mediator, type, price);
    }
    // 和中介联系(沟通)
    public void contact(String message) {
    
    
        mediator.trade(message,this);
    }

}

具体中介类

public class MediatorStructure extends Mediator{
    
    
    //聚合房主和房客对象
    private List<Person> persons=new ArrayList<>();
    //添加客户
    public void setPersons(Person person) {
    
    
        persons.add(person);
    }
    //获取客户
    public List<Person> getPersons() {
    
    
        return persons;
    }
    @Override
    //为租客匹配合适的房子
    public void trade(String message, Person customer) {
    
    
        Iterator<Person> iterator = persons.iterator();
        while (iterator.hasNext()){
    
    
            Person person = iterator.next();
            if(person.getType()==customer.getType()){
    
    
                continue;
            }
            if (customer.getType()==1){
    
    
                //当前顾客表示是房主
                if (person.getPrice()==customer.getPrice()){
    
    
                    //说明价格符合可以进行交易
                    person.getMessage(customer.getName()+message+"你要租住吗");
                }
            }else{
    
    
                //说明当前顾客是租客
                if (person.getPrice()==customer.getPrice()){
    
    
                    //说明价格符合可以进行交易
                    person.getMessage(customer.getName()+message+"你要租给他吗");
                }
            }
        }
    }
}

测试

public class Client {
    
    
    public static void main(String[] args) {
    
    
        // 中介者对象
        MediatorStructure mediator = new MediatorStructure();
        // 租房者对象
        Tenant tenant1 = new Tenant("租房者1",mediator,0,2000);
        Tenant tenant2 = new Tenant("租房者2",mediator,0,2000);
        // 房主对象
        HouseOwner houseOwner1 = new HouseOwner("房东1",mediator, 1,3000);
        HouseOwner houseOwner2 = new HouseOwner("房东2",mediator, 1,2000);
        HouseOwner houseOwner3 = new HouseOwner("房东3",mediator, 1,2500);
        HouseOwner houseOwner4 = new HouseOwner("房东4",mediator, 1,4000);
        // 中介者要知道具体的房主和租房者
        mediator.setPersons(tenant1);
        mediator.setPersons(tenant2);
        mediator.setPersons(houseOwner1);
        mediator.setPersons(houseOwner2);
        mediator.setPersons(houseOwner3);
        mediator.setPersons(houseOwner4);
        tenant1.contact("要租2000的房子");
    }
}

存在的问题

优点

  • 松散耦合

    • 中介者模式通过把多个同事对象之间的交互封装到中介者对象里面,从而使得同事对象之间松散耦合,基本上可以做到互补依赖。这样一来,同事对象就可以独立地变化和复用,而不再像以前那样 “牵一处而动全身” 了。
  • 集中控制交互

    • 多个同事对象的交互,被封装在中介者对象里面集中管理,使得这些交互行为发生变化的时候,只需要修改中介者对象就可以了,当然如果是已经做好的系统,那么就扩展中介者对象,而各个同事类不需要做修改。
  • 一对多关联转变为一对一的关联

    • 没有使用中介者模式的时候,同事对象之间的关系通常是一对多的,引入中介者对象以后,中介者对象和同事对象的关系通常变成双向的一对一,这会让对象的关系更容易理解和实现。

缺点:

  • 当同事类太多时,中介者的职责将很大,它会变得复杂而庞大,以至于系统难以维护

适用场景

  • 系统中对象之间存在复杂的引用关系,系统结构混乱且难以理解。
  • 当想创建一个运行于多个类之间的对象,又不想生成新的子类时。

中介者模式和代理模式的区别

在现实生活中,如房屋中介、买房人、卖房人,房屋中介是一个中介,因为它担任买房人和卖房人之间的相互通讯

房屋中介也是一个代理,它在卖房人眼前是买房人的代理,在卖房人眼前是买房人的代理;

最后房屋中介也是一个桥接,用于连接买房人和卖房人。那这字面意思相似的三者到底有什么不同的应用场景。

代理模式

  1. 最常见的就是数据库中间件,他们代理了数据库的访问,访问一个集群跟访问一个单机数据库一样。
  2. 你想访问 Facebook 或者 Twitter ,如何绕过 GFW?找个代理网站
  3. 生活中有很多实际的案例,比如说“代购”

特点

  1. 一对一,这个代理只能代表一个对象;

  2. 只能代理一方,也就是 PB 是B的代理,A能够通过PB访问B,但是B不能通过PB访问A;

中介模式

1、中国加入 WTO 之前是各个国家相互贸易,结构复杂,现在是各个国家通过 WTO 来互相贸易。

2、机场调度系统。

3、MVC 框架,其中C(控制器)就是 M(模型)和 V(视图)的中介者。

特点

  1. 多对多,这些被管理的对象之间都可以通信,它们的业务关系应该是交织在一起的;

  2. A能够通过中介访问B,B也能够通过中介访问A;

桥接模式

  1. 现需要提供大中小3种型号的画笔,能够绘制5种不同颜色,如果使用蜡笔,我们需要准备3*5=15支蜡笔,也就是说必须准备15个具体的蜡笔类。而如果使用毛笔的话,只需要3种型号的毛笔,外加5个颜料盒,用3+5=8个类就可以实现15支蜡笔的功能。
  2. 不同电脑可以连接不同的手机
  3. 发送多种类型的消息(qq,email),每种消息都有不同的消息等级(普通消息,紧急消息等)

特点

  1. 一对多的关系,一个类可以有很多其他属性;

  2. 桥接夸大不是对象之间的通信,而是拥有某些属性;

总结

  1. 我们可以看出,中介者模式和代理模式比较相似,他俩夸大的是通信,桥接模式夸大的时候拥有属性;

  2. 中介者模式是多对多通信,代理是一对一通信,桥接是一对多;

  3. 代理是通信只能从一方到另外一方,中介者是双向都可以通信

猜你喜欢

转载自blog.csdn.net/qq_50985215/article/details/130970434