设计模式之工厂模式(一)

介绍工厂模式

工厂模式创建对象(视为工厂里的产品)时无需指定创建对象的具体类。

工厂模式定义一个用于创建对象的接口,这个接口由子类决定实例化哪一个类。该模式使一个类的实例化延迟到了子类。而子类可以重写接口方法以便创建的时候指定自己的对象类型。

这个模式十分有用,尤其是创建对象的流程赋值的时候,比如依赖于很多设置文件等。并且,你会经常在程序里看到工厂方法,用于让子类类定义需要创建的对象类型。

工厂模式例子1

var productManager = {};//我是产品经理对象

//我是产品经理对象下的产品A 我是一个构造器 提供给工厂创建床品的一个模型
productManager.createProductA = function() {
    console.log('产品A');
}

//我是产品经理对象下的产品B 我是一个构造器 提供给工厂创建床品的一个模型
productManager.createProductB = function() {
    console.log('产品B');
}

//我是产品经理对象下的工厂 我的使命是为产品经理创造产品
productManager.factory = function(typeType) {
    return new productManager[typeType];
}

//开始创造产品A
productManager.factory("createProductA");//产品A

//开始创造产品B
productManager.factory("createProductB");//产品B

工厂模式例子2

详细解析在项目中的需求和如何使用工厂模式

假如我们想在网页面里插入一些元素,而这些元素类型不固定,可能是图片,也有可能是连接,甚至可能是文本,根据工厂模式的定义,我们需要定义工厂类和相应的子类,我们先来定义子类的具体实现(也就是子函数):

var page = page || {};
page.dom = page.dom || {};
//子函数1:处理文本
page.dom.Text = function () {
    this.insert = function (where) {
        var txt = document.createTextNode(this.url);
        where.appendChild(txt);
    };
};

//子函数2:处理链接
page.dom.Link = function () {
    this.insert = function (where) {
        var link = document.createElement('a');
        link.href = this.url;
        link.appendChild(document.createTextNode(this.url));
        where.appendChild(link);
    };
};

//子函数3:处理图片
page.dom.Image = function () {
    this.insert = function (where) {
        var im = document.createElement('img');
        im.src = this.url;
        where.appendChild(im);
    };
};

那么我们如何定义工厂处理函数呢?其实很简单:

page.dom.factory = function (type) {
    return new page.dom[type];
}

使用方式如下:

var o = page.dom.factory('Link');
o.url = 'http://www.huanghanlian.com';
o.insert(document.body);

var f = page.dom.factory('Text');
f.url = '欢迎来到继小鹏的博客';
f.insert(document.body);

运行结果

image.png

工厂模式进阶

下面这个例子中,是应用了工厂方法对第26章构造函数模式代码的改进版本:

var Car = (function () {
    var Car = function (model, year, miles) {
        this.model = model;
        this.year = year;
        this.miles = miles;
    };
    return function (model, year, miles) {
        return new Car(model, year, miles);
    };
})();

var tom = new Car("Tom", 2009, 20000);
var dudu = new Car("Dudu", 2010, 5000);

通过工厂模式思想和构造函数模式编写组件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<div id="test"></div>
<div id="test2"></div>
<div id="test3"></div>
</body>
<script type="text/javascript">
(function() {
    var Countdown = function(el, opts) {
        var self = this;
        this.container = el;
        this._hander = null;
        var defaults = {
            'start': 100,
            'end': 0,
            'interval': 1000, //多久倒计时一次 单位:ms
        }
        opts = opts || {};
        for (var w in defaults) {
            if ("undefined" == typeof opts[w]) {
                opts[w] = defaults[w];
            }
        }
        this.params = opts;
        this.init();
    }
    Countdown.prototype = {
        //初始化
        init: function() {
            var self = this;
            //开始计数
            self.count();
        },
        //计数
        count: function() {
            var self = this;
            self.container.innerHTML = self.params.start;
            this._hander = setInterval(function() {
                self.params.start -= 1;
                self.container.innerHTML = self.params.start;
                if (self.params.start <= self.params.end) {
                    clearInterval(self._hander);
                    //self.params.countEnd();
                }
            }, self.params.interval);
        },
    }
    window.countdown = Countdown;
})();
new countdown(document.getElementById("test"));
new countdown(document.getElementById("test2"), {
    start: 50,
    end: 48
});
new countdown(document.getElementById("test3"), {
    start: 80,
    end: 60
});
</script>
</html>
image.png

什么时候使用工厂模式

以下几种情景下工厂模式特别有用:

对象的构建十分复杂
需要依赖具体环境创建不同实例
处理大量具有相同属性的小对象

什么时候不该用工厂模式

不滥用运用工厂模式,有时候仅仅只是给代码增加了不必要的复杂度,同时使得测试难以运行下去。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 设计模式汇总 一、基础知识 1. 设计模式概述 定义:设计模式(Design Pattern)是一套被反复使用、多...
    MinoyJet阅读 3,984评论 1 15
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,780评论 18 399
  • 设计模式基本原则 开放-封闭原则(OCP),是说软件实体(类、模块、函数等等)应该可以拓展,但是不可修改。开-闭原...
    西山薄凉阅读 3,897评论 3 14
  • 实践篇共分为4个小节:跨域愤怒、消除罪恶感、克服不安以及避免情绪低落。 首先说跨越愤怒。作者选取了员工中村和管理者...
    全民啃书阅读 313评论 0 0
  • 上一章 文|莹莹 过了好久,我才意识到自己失态了,陈信他什么都不知道。我走到洗手间里洗了一把脸,拿出化妆包重新化了...
    莹莹in阅读 1,000评论 6 21