Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 中介者与观察者面向对象设计模式_Oop_Design Patterns_Observer Pattern_Mediator - Fatal编程技术网

Oop 中介者与观察者面向对象设计模式

Oop 中介者与观察者面向对象设计模式,oop,design-patterns,observer-pattern,mediator,Oop,Design Patterns,Observer Pattern,Mediator,我一直在阅读,为了解决我的一些问题,遇到了中介模式 我之前在我的项目中使用了Observer来制作一些GUI应用程序。我有点困惑,因为我没有发现两者之间的巨大差异。我浏览了一下,想找出不同之处,但找不到任何适合我的问题的答案 有谁能帮我用一个很好的例子来区分这两者吗?这些模式在不同的情况下使用: 当您有两个子系统具有某种依赖关系,其中一个子系统需要更改时,可以使用中介模式,并且由于您可能不想更改依赖于另一个子系统的系统,因此可能需要引入一个中介,它将解耦它们之间的依赖关系。这样,当其中一个子系统

我一直在阅读,为了解决我的一些问题,遇到了中介模式

我之前在我的项目中使用了Observer来制作一些GUI应用程序。我有点困惑,因为我没有发现两者之间的巨大差异。我浏览了一下,想找出不同之处,但找不到任何适合我的问题的答案


有谁能帮我用一个很好的例子来区分这两者吗?

这些模式在不同的情况下使用:

当您有两个子系统具有某种依赖关系,其中一个子系统需要更改时,可以使用中介模式,并且由于您可能不想更改依赖于另一个子系统的系统,因此可能需要引入一个中介,它将解耦它们之间的依赖关系。这样,当其中一个子系统发生更改时,您所要做的就是更新中介

当一个类希望允许其他类注册自己并在事件发生时接收通知时,可以使用观察者模式,例如。G按钮列表器等

这两种模式都允许较小的耦合,但有很大不同。

观察者模式: 定义对象之间的一对多依赖关系,以便当一个对象更改状态时,自动通知并更新其所有依赖项

调解人模式: 定义一个对象,该对象封装了一组对象的交互方式。Mediator通过防止对象彼此显式引用来促进松散耦合,并允许您独立地改变它们的交互

资料来源:

例如:

观察者模式: 类,可以有0个或多个O类型的观察者注册。当系统中的某些内容发生更改时,它会通知所有观察者

调解人模式:
您有一些类X的实例(甚至可能有几种不同的类型:X、Y和Z),它们希望彼此通信(但您不希望每个实例都有对彼此的显式引用),因此您创建了一个中介类M。X的每个实例都有对共享实例M的引用,通过它,它可以与X(或X、Y和Z)的其他实例进行通信。

在创造术语“观察者和中介者”、“设计模式”、“可重用面向对象软件的元素”的原著中,它说中介者模式可以通过使用观察者模式来实现。但是,它也可以通过让同事(大致相当于观察者模式的主题)引用中介类或中介接口来实现

在很多情况下,当您想要使用观察者模式时,关键是一个对象不应该知道其他对象正在观察它的状态

中介更为具体,它避免了类直接通信,而是通过中介进行通信。这有助于单一责任原则,因为它允许将通信转移到只处理通信的类

一个典型的中介示例是在GUI中,这种幼稚的方法可能会导致按钮单击事件上的代码显示“如果Foo面板被禁用,而Bar面板上有一个标签显示“请输入日期”,则不要调用服务器,否则继续”,中介模式可能会显示“我只是一个按钮,不知道Foo面板和吧台面板上的标签,所以我只想问我的调解人现在打电话给服务器是否合适。”

或者,如果中介是使用观察者模式实现的,则按钮会说“嘿,观察者(包括中介),我的状态已更改(有人单击了我)。在我的示例中,直接引用中介可能没有那么大意义,但在许多情况下,使用观察者模式来实现中介是有意义的,观察者和中介之间的区别更多的是意图,而不是代码本身的区别。

Observer 1.没有
  • 客户1:嘿主题,你什么时候换

  • 客户2:你什么时候改变了主题的?我没有注意到

  • 客户3:我知道主题已经改变

2.与
  • 客户端保持沉默
  • 过了一段时间
  • 主题:亲爱的客户,我变了

调解人 1.没有
  • 客户1:嘿出租车1,带我去哪里
  • 客户2:嘿出租车1,带我去哪里
  • 客户1:嘿出租车2,带我去哪里
  • 客户2:嘿出租车2,带我去哪里
2.与
  • 客户1:嘿出租车中心,请给我搭辆出租车
  • 客户2:嘿出租车中心,请给我搭辆出租车

@cdc出色地解释了意图的不同

我会在上面添加更多信息

:允许将一个对象中的事件通知给不同的对象集(不同类的实例)

:集中从特定类创建的一组对象之间的通信

中介模式的结构来自:

调解人:定义同事之间的通信接口

同事:是一个抽象类,它定义同事之间要通信的事件

ConcreteMediator:通过协调同事对象实现合作行为,并维护其同事

具体同事:实现通过中介接收的通知操作,该通知操作由其他同事生成
import java.util.List;
import java.util.ArrayList;

/* Define the contract for communication between Colleagues. 
   Implementation is left to ConcreteMediator */
interface Mediator{
    public void register(Colleague colleague);
    public void unregister(Colleague colleague);
}
/* Define the contract for notification events from Mediator. 
   Implementation is left to ConcreteColleague
*/
abstract class Colleague{
    private Mediator mediator;
    private String name;

    public Colleague(Mediator mediator,String name){
        this.mediator = mediator;
        this.name = name;
    }
    public String toString(){
        return name;
    }
    public abstract void receiveRegisterNotification(Colleague colleague);
    public abstract void receiveUnRegisterNotification(Colleague colleague);    
}
/*  Process notification event raised by other Colleague through Mediator.   
*/
class ComputerColleague extends Colleague {
    private Mediator mediator;

    public ComputerColleague(Mediator mediator,String name){
        super(mediator,name);
    }
    public  void receiveRegisterNotification(Colleague colleague){
        System.out.println("New Computer register event with name:"+colleague+
        ": received @"+this);
        // Send further messages to this new Colleague from now onwards
    }
    public  void receiveUnRegisterNotification(Colleague colleague){
        System.out.println("Computer left unregister event with name:"+colleague+
        ":received @"+this);
        // Do not send further messages to this Colleague from now onwards
    }
}
/* Act as a central hub for communication between different Colleagues. 
   Notifies all Concrete Colleagues on occurrence of an event
*/
class NetworkMediator implements Mediator{
    List<Colleague> colleagues = new ArrayList<Colleague>();

    public NetworkMediator(){

    }

    public void register(Colleague colleague){
        colleagues.add(colleague);
        for (Colleague other : colleagues){
            if ( other != colleague){
                other.receiveRegisterNotification(colleague);
            }
        }
    }
    public void unregister(Colleague colleague){
        colleagues.remove(colleague);
        for (Colleague other : colleagues){
            other.receiveUnRegisterNotification(colleague);
        }
    }
}

public class MediatorPatternDemo{
    public static void main(String args[]){
        Mediator mediator = new NetworkMediator();
        ComputerColleague colleague1 = new ComputerColleague(mediator,"Eagle");
        ComputerColleague colleague2 = new ComputerColleague(mediator,"Ostrich");
        ComputerColleague colleague3 = new ComputerColleague(mediator,"Penguin");
        mediator.register(colleague1);
        mediator.register(colleague2);
        mediator.register(colleague3);
        mediator.unregister(colleague1);
    }
}
New Computer register event with name:Ostrich: received @Eagle
New Computer register event with name:Penguin: received @Eagle
New Computer register event with name:Penguin: received @Ostrich
Computer left unregister event with name:Eagle:received @Ostrich
Computer left unregister event with name:Eagle:received @Penguin
function Person(name) {
    let self = this;
    this._name = name;
    this._chat = null;

    this._receive(from, message) {        
        console.log("{0}: '{1}'".format(from.name(), message));
    }
    this._send(to, message) {
        this._chat.message(this, to, message);
    }
    return {
        receive: (from, message) => { self._receive(from, message) },
        send: (to, message) => { self._send(to, message) },
        initChat: (chat) => { this._chat = chat; },
        name: () => { return this._name; }
    }
}


function ChatMediator() {
    let self = this;
    this._persons = [];    

    return {
        message: function (from, to, message) {
            if (self._persons.indexOf(to) > -1) {
                self._persons[to].receive(from, message);
            }
        },
        register: function (person) {
            person.initChat(self);
            self._persons.push(person);
        }
        unRegister: function (person) {
            person.initChat(null);
            delete self._persons[person.name()];
        }
    }
};

//Usage:
let chat = new ChatMediator();

let colton = new Person('Colton');
let ronan = new Person('Ronan');

chat.register(colton);
chat.register(ronan);

colton.send(colton, 'Hello there, nice to meet you');
ronan.send(ronan, 'Nice to meet you to');

colton.send(colton, 'Goodbye!');
chat.unRegister(colton);
function AmbulanceObserver(name) {
    let self = this;
    this._name = name;
    this._send(address) {
        console.log(this._name + ' has been sent to the address: ' + address);
    }
    return {
        send: (address) => { self._send(address) },
        name: () => { return this._name; }
    }
}


function OperatorObservable() {
    let self = this;
    this._ambulances = [];    

    return {
        send: function (ambulance, address) {
            if (self._ambulances.indexOf(ambulance) > -1) {
                self._ambulances[ambulance].send(address);
            }
        },
        register: function (ambulance) {
            self._ambulances.push(ambulance);
        }
        unRegister: function (ambulance) {
            delete self._ambulances[ambulance.name()];
        }
    }
};

//Usage:
let operator = new OperatorObservable();

let amb111 = new AmbulanceObserver('111');
let amb112 = new AmbulanceObserver('112');

operator.register(amb111);
operator.register(amb112);

operator.send(amb111, '27010 La Sierra Lane Austin, MN 000');
operator.unRegister(amb111);

operator.send(amb112, '97011 La Sierra Lane Austin, BN 111');
operator.unRegister(amb112);