专栏首页用户1096981的专栏大话设计模式(二)- 工厂模式

大话设计模式(二)- 工厂模式

大话设计模式(二)- 工厂模式

工厂模式: 用来创建对象的创建型模式,在上一章的ajax封装中,我们利用简单工厂创建了ajax框架,而不用去关注内部实现。这也是工厂模式的好处之一。通过使用工厂方法而不是new关键字及具体类,你可以把所有实例化代码集中在一个位置,可以大大简化更换所用的类或在运行期间动态选择所用的类的工作。

简单工厂

应用场景在上一篇文章给过, 在创建ajax对象时,我们不关注ajax 内部的对象如何实现,通过判断浏览器的类型,case到不同的ajax对象,达到实例集中管理,并不关注内部实现的目的。

以下是简单的工厂的实现代码。

// 工厂方法 
let  factory = function (role) {
function User(obj) {
    this.name = obj.name;
    this.role = obj.role;
}
switch(role) {
    case 'superman':
    return new User({ name: '平台用户', role: ['主页', '登录页'] })
    break;
    case 'man':
    return new User({ name: '游客', role: ['登录页']})
    break;
    default:
    throw new Error('参数错误')
}
}
// 工厂方法创建不同的实例 
let superman = factory('superman');
let man = factory('man');
// 简单工厂的弊端会导致如果需要更多实例需要维护一个超级函数

应用的实际例子

var Dialog = (function(){
  var createNotice = function(){
    return '<div>notice</div>';
  }
  var createToast = function(){
    return '<div>toast</div>';
  }
  var createWarnin = function(){
 return '<div>warnin</div>';
  }
  var Dialog = function(){
 this.element = '';
 this.name = '';
 this.show = function(){
   console.log(this.name + ' is show -> ' + this.element);
 };
  }
  
  return {
 factory: function(arg){
   var _dialog;
   if(arg === 'notice'){
     _dialog = new Dialog();
     _dialog.element = createNotice();
     _dialog.name = 'notice';
     }else if(arg === 'toast'){
     _dialog = new Dialog();
     _dialog.element = createToast();
     _dialog.name = 'toast';
   }else if(arg === 'warnin'){
     _dialog = new Dialog();
     _dialog.element = createWarnin();
     _dialog.name = 'warnin';
   }
   return _dialog;
 }
  }
})();
var notice = Dialog.factory('notice');
var toast = Dialog.factory('toast');
var warnin = Dialog.factory('warnin');
toast.show(); //toast is show -> <div>toast</div>
notice.show(); //notice is show -> <div>notice</div>
warnin.show(); //warnin is show -> <div>warnin</div>

简单工厂的适用场景: 简单、 可穷举的工厂实例。因为工厂的方法足够简单,而一个大型项目中往往需要我们进行大批量的拓展,此时简单工厂已经不符合软件的开闭原则,我们并不是每次都要改实现。

开闭原则:对扩展开放,对修改源码行为关闭。

工厂方法

工厂方法: 是在简单工厂上的再拓展,通过new关键字进行实例的创建,此时在创建时遍会再次执行构造函数 对构造的实例进行初始化。

以下是简单工厂实现一个返回角色权限的例子

// 创建一个工厂方法来返回不同的方法
let factory = function (role) {
    if(this instanceof factory) {
        var s = new this[role]();
        return s;
    } else {
        return new factory(role);
    }
}
// 下一次新增新的特性时只需要在函数上绑定数据即可
factory.prototype = {
    admin: function() {
        this.name = '平台用户';
        this.role = ['登录页', '主页']

    },
    common: function() {
        this.name = '游客';
        this.role = ['登录页']
    },
    test: function() {
        this.name = '测试';
        this.role =  ['登录页', '主页', '测试页'];
        this.test = '我还有一个测试属性哦'
    }
}
// 工厂方法创建
let admin = new factory('admin');
let common = new factory('common');
let test = new factory('test');

此时当我们需要给角色增加新特性,或者增加新角色时,只需要在原型上增加新的角色or 新的方法即可,此时即达到了工厂方法的扩展。

抽象工厂

江湖传言, 没有什么是不能通过增加一个抽象层解决的。所以抽象工厂更像是一个供应链,或者说是一个提供一个大而全功能的百货公司,通过不同需求提供不同工厂产出的货物。

以下是抽象工厂的代码实现 代码源自知乎,https://zhuanlan.zhihu.com/p/55840258

abstract class Department {
  // 初始化name成员,参数属性
  constructor(public name: string){
  }
  printName(): void{
    console.log('Department name: ' + this.name);
  }
  abstract printMeeting(): void; // 必须在派生类中实现
}
class AccountingDepartment extends Department {
  constructor() {
    super('Accounting and Auditing'); // 在派生类的构造函数中必须调用super()
  }
  printMeeting(): void{
    console.log('The Accounting Department meets each Monday at 10am.');
  }
  generateReports(): void{
    console.log('Generating accounting reports...')
  }
}
let department: Department; // 允许创建一个对抽象类型的引用
department = new Department(); // 错误:不能创建一个抽象类的实例
department = new AccountingDepartment(); // 允许对一个抽象子类进行实例化和赋值
department.printName();
department.printMeeting();
department.generateReports(); // 错误:方法在声明的抽象类种不存在

抽象类像是一个百货公司,定义了公司是发展方向,提供的东西,而真正提供供货货源的人可能来自京东 淘宝 拼多多,这是我对抽象工厂的理解。

思考题?

在实际应用场景中,你是否有使用抽象工厂,工厂方法, 简单工厂呢?

昨日算法题答案。

/*
 * @lc app=leetcode.cn id=1 lang=javascript
 *
 * [1] 两数之和
 */

// @lc code=start
/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[]}
 */
var twoSum = function (nums, target) {
  // 设置容器对象
  var map = {};
  // 遍历数组
  for (let index = 0; index < nums.length; index++) {
    // 当数组中存在
    if (map[target - nums[index]] >= 0) {
      return [map[target - nums[index]], index];
    }
    map[nums[index]] = index;
  }
};

此处使用在对象中找看是否找得到的方式来锁定了数组的下标,采用这种查找的方式在很多求索引的题目中经常会遇到,本次也是一个比较经典的案例。你还有其他的解法吗,欢迎在下方留言哟。

每日一道算法题

给定一个排序的整数数组(升序)和一个要查找的整数target,用O(logn)的时间查找到target第一次出现的下标(从0开始),如果target不存在于数组中,返回-1。

文章分享自微信公众号:
微瞰技术

本文参与 腾讯云自媒体分享计划 ,欢迎热爱写作的你一起参与!

作者:夏天的恶
原始发表时间:2020-12-28
如有侵权,请联系 cloudcommunity@tencent.com 删除。
登录 后参与评论
0 条评论

相关文章

  • 【大话设计模式】——工厂模式家族

    在工厂模式家族中最出名的是工厂三姐妹,根据抽象的程度不同分为简单工厂、工厂模式和抽象工厂模式。他们在我们平时的编程中会经常使用。所以我们应该详细地了解一下他们三...

    程序猿小亮
  • 大话设计模式之简单工厂模式

      最近朋友推荐了一本书《大话设计模式》,此书刚刚到,博主也还没开始看,希望以博文的方式与大家一起分享,一起学习.

    Wyc
  • 大话设计模式笔记(一)——设计模式概论和简单工厂模式

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    逝兮诚
  • 设计模式(二) 抽象工厂模式

    前面我们说了工厂方法模式,当只需要生产某一种类的时候可以使用。如果我们需要生产多类产品,就可以考虑使用抽象工厂模式。

    乐百川
  • 大话设计模式笔记(五)——代理模式和工厂方法模式

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    逝兮诚
  • 设计模式(二)抽象工厂模式

    抽象工厂模式是一种创建型设计模式, 它能创建一系列相关的对象, 而无需指定其具体类。

    lomtom
  • 设计模式之工厂模式(二)

    之前已经带大家稍微入门了工厂模式(即简单工厂模式)的方法,没看过的朋友可以移步去查看一番。设计模式之工厂模式(一)。今天我们继续吃着披萨,学习着工厂模式的接下来...

    程序员小跃
  • 大话设计模式--第一章 简单工厂设计模式

    从这四个方面考虑. 上面这段代码, 维护性差, 改一个地方很可能或误改正确的地方; 复用性, 除了计算器, 其他地方基本不可用. 扩展性也不好, 添加一个开方,...

    用户7798898
  • 大话设计模式--第二章 策略设计模式

    现在有一个需求: 给商场做一个收银软件. 营业员根据客户购买的产品的单价和数量, 向客户打印小票。

    用户7798898
  • 设计模式之二(简单工厂模式)

      简单工厂模式根据提供的数据或者参数返回几个可能的类中的一个实例,说通俗点有点像面向对象编程中的多态性,一个基类,有多个派生类,在另外的调用程序中,根据参数来...

    aehyok
  • Java设计模式之(二)——工厂模式

    定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

    用户4268038
  • 设计模式之二(简单工厂模式)

      简单工厂模式根据提供的数据或者参数返回几个可能的类中的一个实例,说通俗点有点像面向对象编程中的多态性,一个基类,有多个派生类,在另外的调用程序中,根据参数来...

    aehyok
  • 设计模式(二):工厂方法模式

    设计模式(二):工厂方法模式

    Java架构师必看
  • Java设计模式之(二)——工厂模式

    定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

    IT可乐
  • Java设计模式(二)抽象工厂模式

    一、场景描述 接《Java设计模式(一)工厂模式》 工厂模式有一缺点,就是破坏了类的封闭性原则。例如,如果需要增加Word文件的数据采集,此时按以下步骤操作: ...

    用户1637609
  • 浅谈设计模式 - 简单工厂模式(二)

    对于学习设计模式,我推荐:《HeadFirst设计模式》和《大话设计模式》。另外设计模式推崇学以致用。看到任何知识之前,先想想我能学到什么,带着问题去看待问题...

    阿东
  • 工厂模式【工厂设计模式】

    定义一个创建产品对象的工厂接口,将产品对象的实际创建工作推迟到具体子工厂类当中。这满足创建型模式中所要求的“创建与使用相分离”的特点。

    高大北
  • “大话”设计模式

    导语:设计模式是无数码农前人在实际的生产项目中经过不断的踩坑、爬坑、修坑的经历总结出来的经验教训,经过抽象之后表达成的概念。能够帮助后来的设计者避免重复同样的错...

    技术zhai

扫码关注腾讯云开发者

领取腾讯云代金券