中介者和观察者模式的结合

中介者简单回顾

中介者模式主要处理的场景就是处理多个类之间的通信, 为了进行统一的管理. 中介者对象就是作为这个统一管理的对象存在, 在中介聚合了所有需要联系的对象

**在中介者中主要的成员主要是: **

  • 抽象的中介者, 这个一看就是核心类, 定义了与其他类进行交流的方法
  • 抽象的联系者类, 这个就是互相需要通信的类咯, 里面聚合了抽象的中介者(因为需要使用他的抽象联系方法)
  • 具体的联系者类这个就不用说了吧, 具体的联系类对象可以实例化的
  • 具体的中介者结构类, 这里面就需要定义一个可以统一管理的所有联系对象的集合了(这里假设集合, 能够统一管理就行,按照自己需求来), 实现具体的交流方法进行管理通信, 所有的通信都通过这个方法来进行控制

抽象的中介者

public abstract class Mediator {
    // 抽象的联系方法, 通过这个给需要联系对象发送消息
    public abstract void constact(String message,Person person);
}

抽象的联系对象

public abstract class Person {
    protected String name;
    // 聚合了中介者对象
    protected Mediator mediator;

    public Person(String name, Mediator mediator) {
        this.name = name;
        this.mediator = mediator;
    }
}

具体联系对象

public class Tenant extends Person {
    public Tenant(String name, Mediator mediator) {
        super(name, mediator);
    }

    //和中介联系(沟通)
    public void constact(String message) {
        // 调用person中聚合的中介者对象的联系方法进行对象之间的通信
        mediator.constact(message,this);
    }

    //获取信息
    public void getMessage(String message) {
        System.out.println("租房者" + name + "获取到的信息是:" + message);
    }
}
public class HouseOwner extends Person {

    public HouseOwner(String name, Mediator mediator) {
        super(name, mediator);
    }

    //和中介联系(沟通)
    public void constact(String message) {
        mediator.constact(message,this);
    }

    //获取信息
    public void getMessage(String message) {
        System.out.println("房主" + name + "获取到的信息是:" + message);
    }
}

具体的中介者对象

public class MediatorStructure extends Mediator {
    //聚合房主和租房者对象 (根据你的需求存储,集合啊,数组啊,多个集合啊,随意看着来就行)
    private HouseOwner houseOwner;
    private Tenant tenant;

    public HouseOwner getHouseOwner() {
        return houseOwner;
    }

    public void setHouseOwner(HouseOwner houseOwner) {
        this.houseOwner = houseOwner;
    }

    public Tenant getTenant() {
        return tenant;
    }

    public void setTenant(Tenant tenant) {
        this.tenant = tenant;
    }
	// 具体的对象交流方法
    public void constact(String message, Person person) {
        if(person == houseOwner) {
            tenant.getMessage(message);
        } else {
            houseOwner.getMessage(message);
        }
    }
}

测试

public static void main(String[] args) {
        //创建中介者对象
        MediatorStructure mediator = new MediatorStructure();

        //创建租房者对象
        Tenant tenant = new Tenant("李四",mediator);
        //创建房主对象
        HouseOwner houseOwner = new HouseOwner("张三",mediator);

        //中介者要知道具体的房主和租房者
        mediator.setTenant(tenant);
        mediator.setHouseOwner(houseOwner);

        tenant.constact("我要租三室的房子!!!");
        houseOwner.constact("我这里有三室的房子,你要租吗?");
}

观察者简单回顾

观察者模式主要就是订阅发布的形式, 观察的主题事件触发时,通知订阅的对象

观察者也差不多, 主要是一下成员

  • 主题: 需要订阅的对象, 也就是这个进行事件分发, 提供对观察者集合的操作
  • 观察者: 接受主题分发的事件提供一个update方法, 供主题对象进行调用(也就是事件触发, 主题就是调用你定义好的update方法)

抽象主题角色类

public interface Subject {
    //添加订阅者(添加观察者对象)
    void attach(Observer observer);

    //删除订阅者
    void detach(Observer observer);

    //通知订阅者更新消息
    void notify(String message);
}

抽象观察者类

public interface Observer {
	// 用来给主题调用的
    void update(String message);
}

具体观察者类,模拟一个

public class WeiXinUser implements Observer {

    private String name;

    public WeiXinUser(String name) {
        this.name = name;
    }
	// 收到通知时的操作, 就简单打印一下收到事件的信息吧
    public void update(String message) {
        System.out.println(name + "-" + message);
    }
}

具体的主题角色类

public class SubscriptionSubject implements Subject {

    //定义一个集合,用来存储多个观察者对象
    private List<Observer> weiXinUserList = new ArrayList<Observer>();

    public void attach(Observer observer) {
        weiXinUserList.add(observer);
    }

    public void detach(Observer observer) {
        weiXinUserList.remove(observer);
    }

    public void notify(String message) {
        //遍历集合
        for (Observer observer : weiXinUserList) {
            //调用观察者对象中的update方法
            observer.update(message);
        }
    }
}

结合

作用: 对项目中复杂依赖的关系管理, 一般是以中介者去管理复杂订阅关系的模型进行构建

结合上面的中介者和观察者简单的例子, 直接就可以看出两个的关系就是中介者去管理观察者, 其实结合我也只是按照自己的想法实现,希望看到这篇的朋友能够给我指出哪些地方需要改进或则有什么别思路,在此感谢

首先, 直接定义出观察者的两个接口: 主题和观察者

public interface Subject {
    void attach();
    
    void detach();
    
    void notify(String message);
}

public interface Observer {
    void update(String message);
}

可以发现观察者的话是直接实现观察者接口就可以了, 但是对于中介者的联系对象来说, 他是需要通过聚合对象中介者来进行联系通信的,所以这里我们需要申明中介者类同时在观察者对象中聚合此中介者类

public abstract class AbstractUser implements Observer{
    protected String name;
    // 聚合中介者
    protected Mediator mediator;

    public AbstractUser(String name, Mediator mediator) {
        this.name = name;
        this.mediator = mediator;
    }
    
    public abstract void contact(String message);
}

具体实现通信类, 搞一个qq和一个微信用户类,好演示

public class QQUser extends AbstractUser {
    public QQUser(String name, Mediator mediator) {
        super(name, mediator);
    }

    @Override
    public void contact(String message) {
        // 中介者只是提供联系方式, 这样你就可以在contact这个具体实现的方法中获取到是谁发送了消息
        // 也可以意味是什么事件触发了, 需要通知谁告诉他这个事件触发了, 这不就是观察者么
        mediator.contact(message, this); 
    }

    @Override
    public void update(String message) {
        System.out.println(name + "收到, 用户更新消息");
    }
}
public class WeiXinUser extends AbstractUser {
    public WeiXinUser(String name, Mediator mediator) {
        super(name, mediator);
    }

    @Override
    public void contact(String message) {
        mediator.contact(message, this);    
    }

    @Override
    public void update(String message) {
        System.out.println(name + "用户收到消息更新的通知");
    }
}

接下来需要修改一上面的主题, 将抽象用户(聚合了中介者对象)AbstractUser加入方法参数中

public interface Subject {
    void attach(AbstractUser user);
    
    void detach(AbstractUser user);
    // predicateUser 用于控制通知哪些用户
    void notify(String message, Predicate<AbstractUser> predicateUser);
}

集合了抽象中介者和主题的抽象类MediatorStructure, 在里面管理了所有的通信对象, 同时实现主题Subject中的所有方法

public abstract class MediatorStructure extends Mediator implements Subject {
    protected List<AbstractUser> userList = new ArrayList<>();

    @Override
    public void attach(AbstractUser user) {
        userList.add(user);
    }

    @Override
    public void detach(AbstractUser user) {
        userList.remove(user);
    }

    @Override
    public void notify(String message, Predicate<AbstractUser> predicateUser) {
        userList.forEach(it -> {
            if (predicateUser.test(it)) {
                it.update(message);
            }
        });
    }
}

定义最后的中介对象实现, 抽象中介者Mediator的联系方法

public class DefaultMediatorStructure extends MediatorStructure{
    // 实现中介者 Mediator 的抽象联系方法
    @Override
    public void contact(String message, AbstractUser user) {
        if (user instanceof QQUser) {
            // 如果是消息来自 qq 用户, 那就通知所有的微信用户
            notify(message, WeiXinUser.class::isInstance);
        } else if (user instanceof WeiXinUser) {
            // 同上,如果消息来自微信用户则通知所有的qq用户
            notify(message, QQUser.class::isInstance);
        }
    }
}

测试

public static void main(String[] args) {
    DefaultMediatorStructure mediatorStructure = new DefaultMediatorStructure();

    QQUser qqUser = new QQUser("QQ用户", mediatorStructure);
    WeiXinUser weixinUser = new WeiXinUser("微信用户", mediatorStructure);

    mediatorStructure.attach(qqUser);
    mediatorStructure.attach(weixinUser);

    qqUser.contact("唉, 一天又过去了"); // 微信用户用户收到消息更新的通知
    System.out.println("----------------------");
    weixinUser.contact("是啊, 一天过得真快, 今天学到了什么呀?"); // QQ用户收到, 用户更新消息
    
    
}
posted on 2022-03-15 23:27  莫铠瑞  阅读(153)  评论(0)    收藏  举报