程序员

设计模式系列之三观察者模式

2016-12-05  本文已影响46人  梦中人在梦中

先来看看观察者模式的定义

观察者模式:定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

Java实现

下面以消息中心的需求作为例子。有一个消息中心,当消息中心收到新消息时,动态通知所有的收听者。

消息中心部分

public interface Subject {
    //- 注册收听者
    public void registerObserver(Observer o);
    //- 移除收听者
    public void removeObserver(Observer o);
    //- 通知收听者
    public void notifyObservers();
}

public class MessageCenter implements Subject {
    private ArrayList<Observer> observers;
    private String message;

    public MessageCenter() {
        //- 保存所有的收听者
        observers = new ArrayList<Observer>();
    }

    public void registerObserver(Observer o) {
        observers.add(o);
    }

    public void removeObserver(Observer o) {
        int i = observers.indexOf(o);
        if (i >= 0) {
            observers.remove(i);
        }
    }
    /**
     * 通知所有人
     */
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.printMessage(message);
        }
    }
    /**
     * 收到新消息触发
     */
    public void newMessage() {
        notifyObservers();
    }

    //模拟收到消息
    public void setMessage(String message) {
        this.message = message;
        newMessage();
    }
}

收听者部分

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

public class UserOne implements Observer {
    private Subject messageCenter;

    public UserOne(Subject messageCenter) {
        this.messageCenter = messageCenter;
        this.messageCenter.registerObserver(this);
    }

    public void printMessage(String message) {
        System.out.println("UserOne:"+message);
    }
}

public class UserTwo implements Observer {
    private Subject messageCenter;

    public UserTwo(Subject messageCenter) {
        this.messageCenter = messageCenter;
        this.messageCenter.registerObserver(this);
    }

    public void printMessage(String message) {
        System.out.println("UserTwo:"+message);
    }
}

测试

public class Test {
    public static void main(String[] args) {
        MessageCenter messageCenter = new MessageCenter();
        UserOne one = new UserOne(messageCenter);
        UserTwo two = new UserTwo(messageCenter);

        //这里One和Two都能收到消息
        messageCenter.setMessage("First Message!");
        //移除用户One
        messageCenter.removeObserver(one);
        //这里就只有UserTwo能收到消息了
        messageCenter.setMessage("Second Message!");
    }
}

JavaScript实现

在javascript中,最常见的例子就是jquery中的自定义事件,当事件触发时,会通知所有的事件收听者。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Demo</title>
</head>
<body>
<button id="ButtonID">Button</button>
<script src="../jquery/jquery-2.1.3.min.js"></script>
<script>
    var $btn = $("#ButtonID");
    $btn.bind("CustomEvent",function (event,param) {
        console.log("我是收听者One");
        console.log(param);
    });
    $btn.bind("CustomEvent",function (event,param) {
        console.log("我是收听者Two");
        console.log(param);
    });
    //执行此段代码,触发事件。在控制台上可以看到One和Two同时被打印出来了
    $btn.trigger("CustomEvent","给收听者的通知");
</script>
</body>
</html>

样例

(function () {
    function MessageCenter() {
        this.observers  = {};
        this.newMessage = "";
    }
    MessageCenter.fn = MessageCenter.prototype;
    //注册收听者
    MessageCenter.fn.registerObserver = function (id,observer) {
        this.observers[id] = observer;
    };
    //移除收听者
    MessageCenter.fn.removeObserver = function (id) {
        delete this.observers[id];
    };
    //通知所有收听者
    MessageCenter.fn.notifyObservers = function () {
        for(var key in this.observers){
            this.observers[key].apply(this,[this.newMessage]);
        }
    };
    //模拟收到新消息
    MessageCenter.fn.setMessage = function (msg) {
        this.newMessage = msg;
        this.notifyObservers();
    };

    /**
     * 收听者UserOne
     * @param subject
     * @constructor
     */
    function UserOne(subject) {
        subject.registerObserver("UserOne",function (msg) {
            console.log("我是UserOne,我收到的消息是:"+msg);
        })
    }

    /**
     * 收听者UserTwo
     * @param subject
     * @constructor
     */
    function UserTwo(subject) {
        subject.registerObserver("UserTwo",function (msg) {
            console.log("我是UserTwo,我收到的消息是:"+msg);
        })
    }

    //测试代码
    var msgCenter = new MessageCenter();
    new UserOne(msgCenter);
    new UserTwo(msgCenter);
    //这里One和Two都能收到消息
    msgCenter.setMessage("First Message!");
    //移除UserOne
    msgCenter.removeObserver("UserOne");
    //这里就只有UserTwo能收到消息了
    msgCenter.setMessage("Second Message!");
})();

上一篇:<a href="http://muchstudy.com/2016/11/28/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E7%B3%BB%E5%88%97%E4%B9%8B%E4%BA%8C%E7%AD%96%E7%95%A5%E6%A8%A1%E5%BC%8F/">设计模式系列之二策略模式</a>
下一篇:<a href="http://muchstudy.com/2016/12/02/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E7%B3%BB%E5%88%97%E4%B9%8B%E5%9B%9B%E8%A3%85%E9%A5%B0%E8%80%85%E6%A8%A1%E5%BC%8F/">设计模式系列之四装饰者模式</a>

上一篇 下一篇

猜你喜欢

热点阅读