观察者模式

时间:2021-1-8 作者:admin

观察者模式

背景

在软件系统中进场遇到这类需求:当一个对象的状态发生改变,某些与它相关的对象也要随之做出相应的变化。这是建立一种 对象域对象之前的依赖关系,一个对象发生变化时将自动通知其他对象,其他对象将做出反应。

我们将发生改变的对象称为观察目标,将被通知的对象称为观察者,一个观察目标可以对应多个观察者,而且这些观察者之间没有相互关系,之后可以根据需要增加和删除贯彻着,是的系统更易于扩展,这就是观察者模式的产生背景。

概念介绍

观察者模式(Observer Pattern):定义对象之间的一种 一对多依赖关系,使得每当一个对象状态发生改变时,其他依赖对象皆得到通知并被自动更新。观察者模式是一种对象行为型模式。

生活场景

所有浏览器事件(鼠标悬浮,按键等事件)都是观察者模式的例子。

模式特点

1.模式组成

在观察着模式中,通常包含以下角色:

a.目标(Subject)

b.观察目标(ConcresteSubject)

c.观察者(Observer)

d.具体观察者(ConcreteObserver)

2.UML类图

观察者模式

3.优点

  • 观察者模式可以实现 表示层和数据逻辑层的分离,并降低观察目标和观察者之间的耦合度;
  • 观察者模式支持简单广播通信,自动通知所有已经订阅过的对象;
  • 观察者模式 符合开闭原则的要求;
  • 观察目标和观察者之间的抽象耦合关系能够单独扩展以及中庸。

4.缺点

  • 当一个观察目标有多个直接或间接的观察者时,通知所有观察者的过程将会话费很多时间。
  • 当观察目标和观察者之间存在循环依赖时,观察目标会触发他们之间进行循环调用,可能导致系统崩溃。
  • 观察者模式缺少相应机制,让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

使用场景

在以下情况下可以使用观察者模式:

  • 在一个抽象模型中,一个对象的行为 依赖于另一个对象的状态。即当目标对象的状态发生改变是,会直接影响到观察者的行为;
  • 一个对象需要通知其他对象发生反应,但不知道对象是谁。
  • 需要在系统中创建一个触发链时,A对象的行为将影响B,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。

实战示例

1.定义观察目标接口 和观察者接口

//观察目标接口
interface Subject {
  addObserver: (observer:Observer) => void;
  deleteObserver:(observver:Observer) => void;
  notifyObservers:() => void;
}

//观察者接口
interface Observer {
  notify:() => void;
}

2.定义具体观察目标

//具体观察目标类
class ConcreteSubject implements Subject {
  private observers: Observer[] = [];

 //添加观察者
 public addObserver(observer:Observer): void {
    console.log(observer, "is pushed~~");
  this.observers.push(observer);
  }

  //删除观察者
  public deleteObserver(observer:Observer): void {
    console.log(observer,"have deleted~~");
  const idx:number = this.observers.indexOf(observer);
  ~idx && this.observsers.splice(idx,1);
  }

  //通知观察者
  public notifyObservers(): void {
    console.log('notify all the observers ',this.observers);
  this.observers.forEach(observer => {
      //调用 notify 方法时可以携带指定参数
      observer.notify();
    })
  }
}

3.定义 具体观察类

//具体观察类
class ConcreteObserver implements Observer {
  constructor(private name:string){}

  notify():void {
    //可以处理其他逻辑
    console.log(`${this.name}has been notified.`);
  }
}

4.测试代码

//测试代码~~~~
function userObserver(): void {
  const subject: Subject = new ConcreteSubject();
 const Leo = new ConcreteObserver('Leo');
 const Robin = new ConcreteObserver('Robin');
 const Pual = new ConcreteObserver('Pual');
 const Lisa = new ConcreteObserver('Lisa');

 subject.addObserver(Leo);
 subject.addObserver(Robin);
 subject.addObserver(Pual);
 subject.addObserver(Lisa);
 subject.notifyObservers();
}

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。