ruby、javascript、php中的观察者模式实现代码

面试被问及到js中的观察者模式,这玩意儿早就了解过,可以说是动态语言中非常有用的一个设计模式,非常惭愧的没有系统的研究过。不过没关系,哪里不会补哪里,立刻动手,用所会的语言都实现一遍。

观察者模式

关于观察者模式,《松本行弘的程序世界》讲的非常清楚:观察者模式是当某个对象状态发生变化时,依存于该状态的全部对象自动得到通知,被观察者和观察者们是一对多的关系。书中还举了一个非常易懂的例子:获取系统当前时间并输出到命令行中。如果要硬编码也很简单,定义一个方法,先获取时间,然后再处理展示。这样获取时间的功能基本就不能复用了,因为带了个处理展示的拖油瓶。

如果用观察者模式则可以这样:定义两个类,一个用于计时,获取当前时间;另一个用于展示时间。展示时间的类就是观察者,这样做的好处是降低相互的依赖性。第一个类改变后不需要处理任何事物,只需要发出通知告诉它的观察者们,具体事物由它们处理。比如有一天我们想换种形式展示时间,或者用多种方式展示时间,完全不需要牵扯到第一个类。

PS:《松本行弘的程序世界》真是一本好书。起初是想把这本书当做ruby教程来读的,后来发现根本不是,书中用非常易懂的语言深入浅出的讲明白了很多深奥的哲学思想。虽然这本书对我这种刚入门的菜鸟来说几乎没有什么实用价值,但是读完之后有种豁然开朗的感觉,是一次非常好的阅读体验。

ruby实现

用ruby实现观察者模式简直简单清晰的令人发指,上代码:

代码如下:

require "observer"
#被观察者
class Subject
    include Observable
    def notify
        #do sth
        changed #更新标志为真
        notify_observers(*args) #如果更新标志为真,调用观察者带参数args的方法
    end
end
#观察者
class Obs
    #回调函数,好像只能这么叫
    def update
        #do sth
    end
end
#实例
sub = Subject.new
sub.add_observer(Obs.new)
sub.notify

没错,就是这么简单。。。
主要是依靠Observer模块,除了上面用到的,此模块还有如下接口:

1.delete_observer(obj) 删除特定的观察者
2.delete_observers 删除全部观察者
3.count_observers 获取观察者数目
4.changed? 检查更新标志

php实现

php实现起来也不麻烦:

代码如下:

//被观察者
class Subject
{
    private $_observers;
    public function __construct() {
        $this->_observers = array();
    }
    public function add_observer($obs) {
        $this->_observers[] = $obs;
    }
    public funtion delete_observer($bos) {
        $index = array_search($bos, $this->_observers);
        unset($this->_observers[$index]);
    }
    public function notify_observers() {
        foreach($this->_observers as $v) {
            $v->update();
        }
    }
}
//观察者
class Observer
{
    public function __construct() {
        do sth;
    }
    public function update() {
        do sth;
    }
}
//实例
$sub = new Subject();
$obs = new Observer();
$sub->add_observer($obs);
$sub->notify_observers();

js实现

js实现起来也不麻烦,就是得写些工具函数方便用,比如删除数组指定的元素。下面只用最简单的实现方法。

代码如下:

//被观察者
function Subject() {
    var _this = this;
    this.observers = [];
    this.addObserver = function(obj) {
        _this.observers.push(obj);
    }
    this.deleteObserver = function(obj) {
        var length = _this.observers.length;
        for(var i = 0; i < length; i++) {
            if(_this.observers[i] === obj) {
                _this.observers.splice(i, 1);
            }
        }
    }
    this.notifyObservers = function() {
        var length = _this.observers.length;
        console.log(length)
        for(var i = 0; i < length; i++) {
            _this.observers[i].update();
        }
    }
}
//观察者
function Observer() {
    this.update = function() {
        alert(1)
    }
}
var sub = new Subject();
var obs = new Observer();
sub.addObserver(obs);
sub.notifyObservers();
var sub = new Subject();

结论:ruby可以让我们专注于程序设计本身,而不是程序的语法和特性。js灵活多变,是一门完备的编程语言除了生孩子什么都能实现,就是玩起来要下点功夫。php嘛,中规中矩,没啥好说的。

这仨程序都跑起来后算是彻底明白这个设计模式了。

(0)

相关推荐

  • php观察者模式应用场景实例详解

    本文实例讲述了php观察者模式的应用.分享给大家供大家参考,具体如下: <?php /** * 观察者模式应用场景实例 * * 免责声明:本文只是以哈票网举例,示例中并未涉及哈票网任何业务代码,全部原创,如有雷同,纯属巧合. * * 场景描述: * 哈票以购票为核心业务(此模式不限于该业务),但围绕购票会产生不同的其他逻辑,如: * 1.购票后记录文本日志 * 2.购票后记录数据库日志 * 3.购票后发送短信 * 4.购票送抵扣卷.兑换卷.积分 * 5.其他各类活动等 * * 传统解决方案: *

  • php设计模式之观察者模式的应用详解

    观察者模式:定义对象间一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新. 观察者类:1.抽象主题角色:主题角色将所有对观察者对象的引用保存在一个集合中,每个主题可以任意多个观察者.抽象主题提供了增加和删除观察者对象的接口.2.抽象观察者角色:为所有的具体观察者定义一个接口,在观察的主题发生改变时更新自己3.具体主题角色:存储相关状态到具体观察者对象,当具体主题的内部状态发生改变时,给所有登记过的观察者发出通知.具体主题角色通常用一个具体子类实现.4.具体观

  • php设计模式 Template (模板模式)

    继承关系由于自身的缺陷,被专家们扣上了"罪恶"的帽子."使用委派关系代替继承关系","尽量使用接口实现而不是抽象类继承"等等专家警告,让我们这些菜鸟对继承"另眼相看".其实,继承还是有很多自身的优点所在.只是被大家滥用的似乎缺点更加明显了.合理的利用继承关系,还是能对你的系统设计起到很好的作用的.而模板方法模式就是其中的一个使用范例. GOF给模板方法(Template Method)模式定义一个操作中的算法的骨架,而将一些步

  • PHP实现的观察者模式实例

    本文实例讲述了PHP实现的观察者模式.分享给大家供大家参考,具体如下: <?php //定义观察者调用接口 class transfer{ protected $_observers = array(); //注册对象 public function register($sub){ $this->_observers[] = $sub; } //外部统一调用 public function trigger(){ if(!empty($this->_observers)){ foreach

  • PHP设计模式之观察者模式(Observer)详细介绍和代码实例

    [意图] 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新[GOF95] 又称为发布-订阅(Publish-Subscribe)模式.模型-视图(Model-View)模式.源-监听(Source-Listener)模式.或从属者(Dependents)模式 [观察者模式结构图] [观察者模式中主要角色] 1.抽象主题(Subject)角色:主题角色将所有对观察者对象的引用保存在一个集合中,每个主题可以有任意多个观察者. 抽象主题提供了增加和

  • php设计模式 Proxy (代理模式)

    代理,指的就是一个角色代表另一个角色采取行动,就象生活中,一个红酒厂商,是不会直接把红酒零售客户的,都是通过代理来完成他的销售业务.而客户,也不用为了喝红酒而到处找工厂,他只要找到厂商在当地的代理就行了,具体红酒工厂在那里,客户不用关心,代理会帮他处理. 代理模式,就是给某一对象提供代理对象,并由代理对象控制具体对象的引用. 代理模式涉及的角色: 抽象主题角色,声明了代理主题和真实主题的公共接口,使任何需要真实主题的地方都能用代理主题代替. 代理主题角色,含有真实主题的引用,从而可以在任何时候操

  • PHP观察者模式原理与简单实现方法示例

    本文实例讲述了PHP观察者模式原理与简单实现方法.分享给大家供大家参考,具体如下: 当一个对象状态发生改变后,会影响到其他几个对象的改变,这时候可以用观察者模式.像wordpress这样的应用程序中,它容外部开发组开发插件,比如用户授权的博客统计插件.积分插件,这时候可以应用观察者模式,先注册这些插件,当用户发布一篇博文后,就回自动通知相应的插件更新. 观察者模式符合接口隔离原则,实现了对象之间的松散耦合. 观察者模式UML图: 在php SPL中已经提供SplSubject和SqlOberve

  • php设计模式 Observer(观察者模式)

    复制代码 代码如下: <?php /** * 观察者模式 * * 定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新 * 能够便利地创建查看目标对象状态的对象,并且提供与核心对象非耦合的指定功能 * 插件系统 */ class Observerable { private $_observers = array(); public function registerObserver($observer) { $this->_observer

  • php单态设计模式(单例模式)实例

    单态设计模式也叫单例模式: 1.单态设计模式含义: 单态模式的主要作用是保证在面向对象编程设计中,一个类只能有一个实例对象存在.作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统全局地提供这个实例.它不会创建实例副本,而是会向单例类内部存储的实例返回一个引用. 2.单台模式的三个关键点: ① 需要一个保存类的唯一实例的静态成员变量: ②构造函数和克隆函数必须声明为私有的,防止外部程序new类从而失去单例模式的意义: ③必须提供一个访问这个实例的公共的静态方法(通常为

  • PHP最常用的2种设计模式工厂模式和单例模式介绍

    1.工厂模式 主要作用是降低耦合度. 复制代码 代码如下: abstract class Operation{ abstract public function getValue($num1,$num2); public function getAttr(){ return 1; } } class Add extends Operation{ public function getValue($num1, $num2){ return $num1+$num2; } } class Sub ex

  • php中的观察者模式简单实例

    观察者模式是设计模式中比较常见的一个模式,包含两个或者更多的互相交互的类.这一模式允许某个类观察另外一个类的状态,当被观察类的状态发生变化时候,观察者会进行得到通知进而更新相应状态. php的SPL标准类库提供了SplSubject和SplObserver接口来实现,被观察的类叫subject,负责观察的类叫observer.这一模式是SplSubject类维护了一个特定状态, 当这个状态发生变化时候,它就会调用notify方法.调用notify方法时,所有之前使用attach方法注册的SplO

  • php中的观察者模式

    观察者模式 复制代码 代码如下: interface Subject { public function Attach($Observer); //添加观察者 public function Detach($Observer); //踢出观察者 public function Notify(); //满足条件时通知观察者 public function SubjectState($Subject); //观察条件 } class Boss Implements Subject { public

随机推荐