Javascript设计模式-04-工厂模式

2023-11-15

Javascript设计模式 - 04 -工厂模式(简单工厂,抽象工厂)

简介

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

个人理解

简单工厂模式接受一个命令,然后将命令的处理分离出去,命名处理函数接受不同的命令,或者根据不同的环境返回不同的对象,返回的对象会在工厂中绑定一些公用的‘零件’(主要是方法)最后返回一个加工后的商品的实例

    // 创建不同交通工具 Transport
    function Car() {
        this.name = 'transport-car';
    }

    function Train() {
        this.name = 'transport-train';
    }

    function Bike() {
        this.name = 'transport-bike';
    }

    // 定义命令处理函数
    function selectTransport(type) {
        var transport;

        switch (type) {
            case 'car':
                transport = new Car();
                break;
            case 'train':
                transport = new Train();
                break;
            case 'bike':
                transport = new Bike();
                break;
            default:
                transport = new Car();
                break;
        }

        return transport;
    }

    // 创建工厂
    function Factory() {
        this.count = 0;
    }

    Factory.prototype.create = function (type) {
        var me = this;
        var transport = selectTransport(type);
        // 绑定公有的方法
        transport.intro = function () {
            console.log('this is ' + this.name + ' count: ' + me.count++);
        }

        return transport;
    }

    // 实例化工厂
    var factory = new Factory();
    // 开始创建
    var train = factory.create('train');
    train.intro(); // this is transport-train count: 0
    // 再创建
    var bike = factory.create('bike');
    bike.intro(); // this is transport-bike count: 1

抽象工厂模式相比于简单工厂模式,真正使用的‘工厂’,是我们抽象出来的工厂的一个子类,同时,命令处理函数不在定义在外边,而是定义在子类的原型上,这样有不同的组装需求,只需要从抽象工厂上继承一个子类,在子类中定义新的命令处理方式就行了。

    // 创建一个用于继承的函数
    function extend(subClass, superClass) {
        // 定义一个中介类
        function F() {}
        // 原型指向父类的原型
        F.prototype = superClass.prototype;
        /*
            子类的原型指向中介类的一个实例,实现继承
            由于 subClass 的原型指向的是 F 的一个实例 而不是 F.prototype 也就是 父类的原型,
            所以子类原型的修改不会将父类的原型也修改掉
        */ 
        subClass.prototype = new F();
        // 上一步得到的子类的原型的构造函数是 Factory ,这里需要把它变回自己本身
        subClass.prototype.constructor = subClass;
    }

    // 创建不同交通工具 Transport
    function Car() {
        this.name = 'transport-car';
    }

    function Train() {
        this.name = 'transport-train';
    }

    function Bike() {
        this.name = 'transport-bike';
    }

    // 创建工厂
    function Factory() {
    }

    Factory.prototype.create = function (type) {
        var me = this;
        // 注:这里改为了调用自身的 selectTransport 方法,Factory 本身没有这个方法,这个方法是子类定义的
        var transport = this.selectTransport(type);
        // 绑定公有的方法
        transport.intro = function () {
            console.log('this is ' + this.name + ' count: ' + me.count++);
        }

        return transport;
    }

    // 新增子类的创建
    function TransportFactory() {
        this.count = 0;
    };
    extend(TransportFactory, Factory); // 继承工厂
    // 子类定义 selectTransport 方法,定义前一定要先继承父类,否则会被覆盖
    TransportFactory.prototype.selectTransport = function (type) {
        var transport;

        switch (type) {
            case 'car':
                transport = new Car();
                break;
            case 'train':
                transport = new Train();
                break;
            case 'bike':
                transport = new Bike();
                break;
            default:
                transport = new Car();
                break;
        }

        return transport;
    }


    // 实例化工厂
    var factory = new TransportFactory();
    // 开始创建
    var train = factory.create('train');
    train.intro();
    // 再创建
    var bike = factory.create('bike');
    bike.intro();

文章列表

  1. javascript设计模式 – 设计原则
  2. JavaScript设计模式–高阶函数
  3. Javascript 设计模式 - 01 - 原型模式
  4. Javascript 设计模式 - 02 - 单例模式
  5. Javascript 设计模式 - 03 - 建造者模式
  6. Javascript 设计模式 - 04 - 工厂模式
  7. Javascript 设计模式 - 05 - 外观模式
  8. Javascript 设计模式 - 06 - 代理模式
  9. Javascript 设计模式 - 07 - 观察者模式(发布订阅模式)
  10. Javascript 设计模式 - 08 - 策略模式
  11. Javascript 设计模式 - 09 - 命令模式
  12. Javascript 设计模式 - 10 - 迭代器模式
  13. Javascript 设计模式 - 11 - 职责链模式
  14. Javascript 设计模式 - 12 - 适配器模式
  15. Javascript 设计模式 - 13 - 模板方法
  16. Javascript 设计模式 - 14 - 组合模式
  17. Javascript 设计模式 - 15 - 享元模式
  18. Javascript 设计模式 - 16 - 中介者模式
  19. Javascript 设计模式 - 17 - 装饰者模式
  20. Javascript 设计模式 - 18 - 状态模式
参考文章
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Javascript设计模式-04-工厂模式 的相关文章

  • 我如何能够以两行显示标题,并且每行的字体大小不同?

    我正在使用 Google Chart API 创建时间线图 并希望将图的标题修改为两行 问题 我如何能够显示具有不同字体大小的两线图表标题 电流输出 理想输出 相关研究 我唯一能找到的是有人试图用饼图来做到这一点 但我尝试了但无法使其发挥作
  • 暂停除了已激活的玩家之外的所有其他玩家。

    我有这个插件 它可以将不同的样式应用于 html5
  • 如何使用 JavaScript 创建链接?

    我有一个标题字符串和一个链接字符串 我不知道如何将两者放在一起以使用 JavaScript 在页面上创建链接 任何帮助表示赞赏 我试图解决这个问题的原因是因为我有一个 RSS 源并且有一个标题和 URL 列表 我想将标题链接到 URL 以使
  • 为什么 iife 在一个简单的例子中不起作用?

    我不明白为什么函数表达式调用不起作用并抛出错误 你能给我解释一下吗 var a function x alert x function a 1 谢谢大家 任务比我想象的要容易得多 这是因为 JS 将 IIFE 解析为函数的参数调用 这样做时
  • 如何在react-bootstrap中禁用表单提交的

    在下面的代码片段中 我有许多文本类型的输入表单 如果用户点击 我似乎会得到相同的合成事件 就像他们按下提交按钮一样 我想忽略作为表单提交 只允许一个人按下 提交 按钮 我删除了一些表单组以减少示例 在所有情况下 按钮或 ENTER 键 e
  • 摩卡 - Chai Karma“套件未定义”

    我对 jscript tdd 很陌生 遇到了问题 希望有人能告诉我我在做什么 在浏览器中运行测试 通过 HTML 文件 一切正常 通过节点和业力运行它们我得到以下异常 我想在 node js 主机的 karma 中使用 Mocha 和 Ch
  • 可以在初始 DOM 解析期间/之前修改 DOM 吗?

    是否可以在初始 DOM 解析期间或之前修改 DOM 或者我是否必须等到 DOM 被解析和构建之后才能与其交互 更具体地说 是否有可能阻止 DOM 中的脚本元素使用用户脚本 内容脚本或 Chrome 或 Firefox 中的类似脚本运行 在解
  • Bootstrap按钮加载+Ajax

    我正在使用 Twitter Bootstrap 的按钮加载状态 http twitter github com bootstrap javascript html buttons http twitter github com bootst
  • 有没有办法使用 Rspec/Capybara/Selenium 将 javascript console.errors 打印到终端?

    当我运行 rspec 时 是否可以让 capybara selenium 向 rspec 报告任何 javascript console errors 和其他异常 我有一大堆测试失败 但当我手动测试它时 我的应用程序正在运行 如果不知道仅在
  • 如何纠正流警告:解构(缺少注释)

    我正在编写一个小型 React Native 应用程序 并且正在尝试使用 Flow 但我无法在任何地方真正获得有关它的正确教程 我不断收到错误 destructuring Missing annotation 有关 station 这段代码
  • Angular - CSS - 自定义类型=文件输入,如何使用按钮而不是标签?

    我制作了一个类型为 file 的自定义输入字段 因为我不喜欢默认的输入字段 为了实现这一目标 我做了
  • Chrome 扩展程序在代码中使用 client_secret

    我正在开发具有自己的 oAuth 授权的 Google Chrome 扩展 当然 我必须使用 client id 和 client secret 作为请求令牌 有什么办法可以向用户隐藏这些数据吗 由于此请求只是 javascript 源代码
  • 使用 CSS 或 Javascript 填充动画

    我只是想知道是否可以使用 CSS 或 javascript 创建填充动画 基本上我想创建一个填充动画 如下图所示 http i40 tinypic com eit6ia png http i40 tinypic com eit6ia png
  • 将 UMD Javascript 模块导入浏览器

    你好 我正在对 RxJS 进行一些研究 我可以通过在浏览器中引用它来使用该库 如下所示 它使用全局对象命名空间变量 Rx 导入 我可以制作可观察的东西并做所有有趣的事情 当我将 src 更改为指向最新的 UMD 文件时 一切都会崩溃 如下所
  • Firebase 函数 onWrite 未被调用

    我正在尝试使用 Firebase 函数实现一个触发器 该触发器会复制数据库中的一些数据 我想观看所有添加的内容votes user vote 结构为 我尝试的代码是 const functions require firebase func
  • 日期出现奇怪的错误,“未捕获非法访问”

    所以我试图找到最新的DateJavascript 可以处理 我把它减少到 9 月 275760 并增加了我开始捕获未捕获的天数illegal access例外new Date 09 24 275760 to new Date 10 13 2
  • 如何使用 crypto-js 解密 AES ECB

    我正在尝试将加密数据从 flash 客户端 发送到服务器端的 javascript 在 asp 中作为 jscript 运行 有几个 javascript Aes 库 但它们实际上没有文档记录 我正在尝试使用 crypto js 但无法让代
  • 从 FileReader 设置背景图像样式

    我正在寻找一种解决方案 允许我从文件上传输入中获取文件并通过设置 document body style backgroundImage 来预览它 以下代码用于在 Image 元素中显示预览 function setImage id tar
  • 如何确定所有角度2分量都已渲染?

    当所有 Angular2 组件完成渲染时 是否会触发一个角度事件 For jQuery 我们可以用 function 然而 对于 Angular2 当domready事件被触发 html 只包含角度组件标签 每个组件完成渲染后 domrea
  • 如何使用asm.js进行测试和开发?

    最近我读到asm js规范 看起来很酷 但是是否有任何环境 工具来开发和测试这个工具 这还只是处于规范阶段吗 您可以尝试使用 emscripten 和 ASM JS 1 并从侧分支在 firefox 构建中运行它 有关 asm js 的链接

随机推荐