zoukankan      html  css  js  c++  java
  • 设计模式之观察者模式

    观察者模式(Observer),其含义是定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式也称为发布-订阅模式。将一个系统分割一系列相互作用的类有一个常见的副作用:需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,因为这样降低了它们的可重用性。 观察者模式的关键对象是目标和观察者,一个目标可以有任意数目的依赖它的观察者,一旦目标的状态发生改变,所有的观察者都得到通知。作为对这个通知的响应,灭个观察者都将查询目标以使其状态与目标的状态同步。目标是通知的发布者,它发出通知时并不需知道谁是它的观察者,可以有任意数目的观察者订阅并接收通知。

    其适用性:

    当一个抽象模型有两个方面,其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用,

    当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变,

    当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之,你不希望这些对象是紧密耦合的。

    其结构图:

                      

    每个subject维护以个Observer的列表,意思是一个目标类可以被多个观察者观察,其可以绑定或解除一个observer;而observer类必须具有在subject改变时,接收到通知后更新相关信息(如状态)。实现如下:

     package org.designpattern.behavioral.observer;

    import java.util.ArrayList;
    import java.util.List;

    public abstract class Subject {
        protected String state;
        protected List<Observer> observers;
        public abstract void attach(Observer observer);
        public abstract void detach(Observer observer);
        public abstract void notice();

        public String getState() {
            return state;
        }

        public void setState(String state) {
            this.state = state;
        }
    }

      每个Subject的子类,在通知改变时会通知所有观察自己的观察者,具体代码可参考本博客的github。

    在一个Observer抽象基类里,会有指定自己要观察的Subject实例,也就是具有该属性,通过记录它的状态来实现。下面是Observer的一个具体子类,其更新操作是记录目标的状态

    package org.designpattern.behavioral.observer;

    public class ConcreteObserverA extends Observer {
        public ConcreteObserverA(Subject subject){
            this.subject = subject;
            this.subject.attach(this);
        }
        @Override
        public void update(Subject subject) {
            //To change body of implemented methods use File | Settings | File Templates.
           this.setState(subject.getState());
        }

    } 

      客户端测试类较为简单:

    package org.designpattern.behavioral.observer;

    public class Main {
        public static void main(String[] args) {
            Subject subject = new ConcreteSubject();
            Observer obsvrA = new ConcreteObserverA(subject);
            Observer obsvrB = new ConcreteObserverB(subject);

            subject.setState("red");
            System.out.println(obsvrA.getState());
            System.out.println(obsvrB.getState());

            subject.notice();
            System.out.println(obsvrA.getState());
            System.out.println(obsvrB.getState());
        }

    } 

      第一次观察者的state都是null,在获取subject通知后,再次获取state就是变成了red。

    观察者模式在书中的例子是关于数据显示问题,这样根据需要做粗不同的显示图。观察者模式和协调者模式一样都是定义一对多的对象关系,此模式可使得对象之间进行同步通信。该模式可与单例模式一起构建一个更改管理其对象,经典的MVC思想非常类似观察者模式,只是观察的对象不同,其是视图页面来观察数据。

  • 相关阅读:
    LeetCode Count of Range Sum
    LeetCode 158. Read N Characters Given Read4 II
    LeetCode 157. Read N Characters Given Read4
    LeetCode 317. Shortest Distance from All Buildings
    LeetCode Smallest Rectangle Enclosing Black Pixels
    LeetCode 315. Count of Smaller Numbers After Self
    LeetCode 332. Reconstruct Itinerary
    LeetCode 310. Minimum Height Trees
    LeetCode 163. Missing Ranges
    LeetCode Verify Preorder Serialization of a Binary Tree
  • 原文地址:https://www.cnblogs.com/kingcucumber/p/3236857.html
Copyright © 2011-2022 走看看