JS设计模式——7.工厂模式(示例-RSS阅读器)

RSS阅读器

由于我们只想跟RSS容器对象打交道,所以用一个工厂来实例化这些内部对象并把它们组装到一个RSS阅读器中.

使用工厂方法在好处在于,我们创建的RSS阅读器类不会与那些成员对象紧密耦合在一起.

RSS阅读器的成员对象

成员对象1: xhr

这个对象就是上一篇中介绍过的,所以就不再说了.

成员对象2: 显示类

为了满足RSS阅读器类的需要,它需要实现几个方法.

var DisplayModule = new Interface('DisplayModule', ['append', 'remove', 'clear']);

var ListDisplay = function(id, parent){

    this.list = document.createElement('ul');

    this.list.id = id;

    parent.appendChild(this.list);

};

ListDisplay.prototype = {

    append: function(text){

        var newEl = document.createElement('li');

        this.list.appendChild(newEl);

        newEl.innerHTML = text;

        return newEl;

    },

    remove: function(el){

        this.list.removeChild('el');

    },

    clear: function(){

        this.list.innerHTML = '';

    }

};

成员对象3: 配置对象

这只是一个对象字面量,它包含着一些借位阅读器类及其成员对象使用的设置

var conf = {

    id: 'con-top-stories',

    feedUrl: 'http://www.baidu.com',

    updateInteval: 60,

    parent: $('feed-readers')

};

RSS阅读对象类

上面介绍的类都由一个名为FeedReader的类组合使用.它用xhr处理器从RSS源获取XML格式的数据并用一个内部方法进行解析,然后用显示模块将解析出来的信息输出到网页上.

var FeedReader = function(display, xhrHandler, conf){

    this.display = display;

    this.xhrHandler = xhrHandler;

    this.conf = conf;



    this.startUpdates();

};

FeedReader.prototype = {

    fetchFeed: function(){

        var that = this;

        var callback = {

            success: function(text, xml) {that.parseFeed(text, xml)},

            failure: function(status) {that.showError(status);}

        };

        this.xhrHandler.request('GET', 'feedProxy.php?feed='+this.conf.feedUrl, callback);

    },

    parseFeed: function(responseText, responseXML){

        this.display.clear();

        var items = responseXML.getElementsByTagName('item');

        for(var i= 0, len=items.length; i<len; i++){

            var title = items[i].getElementsByTagName('title')[0];

            var link = items[i].getElementsByTagName('link')[0];

            this.display.append('<a href="'+link.firstChild.data+'">'+this.firstChild.data+'</a>');

        }

    },

    showError: function(statusCode){

        this.display.clear();

        this.display.append('Error fetching feed.');

    },

    stopUpdates: function(){

        clearInterval(this.interval);

    },

    startUpdates: function(){

        this.fetchFeed();

        var that = this;

        this.interval = setInterval(function(){that.fetchFeed();}, this.conf.updateInteval*1000);

    }

};

使用工厂方法

现在还差一个部分,即把所有这些类和对象拼装起来的那个工厂方法.它被实现为一个简单工厂,如下所示.

var FeedManager = {

    createFeedReader: function(conf){

        var displayModule = new ListDisplay(conf.id+'-display',conf.parent);

        Interface.ensureImplements(displayModule, DisplayModule);



        var xhrHandler = XhrManager.createXhrHandler();

        Interface.ensureImplements(xhrHandler, AjaxHandler);



        return new FeedReader(displayModule, xhrHandler, conf);

    }

}

使用这个工厂方法,可以把FeedReader类所需的复杂设置封装起来,并且可以确保其成员对象都实现所需接口.

它还把对所使用在特定模块的硬性设定集中在一个位置(ListDisplay和createXhrHandler),哪天要是想使用ParagraphDisplay和QueueHandler,做起来也同样简单,只要改改这个工厂方法内部的代码就行.

等.

你可能感兴趣的:(设计模式)