(四)单例模式与工厂模式

在未读《JavaScript设计模式》这本书前,在我的印象里,单例模式就是每个类只会产生一个实例,非常简单。在细看到这个模式时候,有些疑惑单例模式与工厂模式的区别,虽然看起来像最大区别在于是否多次实例化。

单例(Singleton)模式

单例模式它限制了类的实例化次数只能一次。在实例不存在的情况下,可以通过一个方法创建一个类来实现创建类的新实例;如果实例已经存在,它会简单返回该对象的引用。(这跟我想的一样)

例子:

var mySingleton = (function () {
  // Instance stores a reference to the Singleton
  var instance;
  function init() {
    // Singleton
    // Private methods and variables
    function privateMethod(){
        console.log( "I am private" );
    }
    var privateVariable = "Im also private";
    var privateRandomNumber = Math.random();
    return {
      // Public methods and variables
      publicMethod: function () {
        console.log( "The public can see me!" );
      },
      publicProperty: "I am also public",
      getRandomNumber: function() {
        return privateRandomNumber;
      }
    };
  };
  return {
    // Get the Singleton instance if one exists
    // or create one if it doesn‘t
    getInstance: function () {
      if ( !instance ) {
        instance = init();
      }
      return instance;
    }
  };
})();

特别地方:

1. 单例不同于静态类(或对象),因为我们可以推迟它们的初始化(通常是因为它们需要的参数信息在类定义时是无法获得的),直到需要使用静态实例时,无需使用资源或内存。

2. 单例的唯一实例能够通过子类去扩展,使用者不用更改代码就能使用一个扩展的实例。

3. 单例将导致测试变困难,不利于单元测试。

何时使用单例(When it really is a singleton):

一个类是否是一个单例,必须确定下面三点:

1. Will every application use this class exactly the same way? (exactly is the key word)

2. Will every application ever need only one instance of this class? (ever and one are the key words)

3. Should the clients of this class be unaware of the application they are part of?

PS:这三点是由文章http://www.ibm.com/developerworks/webservices/library/co-single/index.html提出。

我的理解是:

1. 是否每个应用程序使用这个类的方式都完全相同?

2. 是否每个应用程序任何时候都只需要一个类的实例?

3. 使用者不需要知道该类是这应用程序的哪个部分?(或许翻译不好)

当满足这三个点,那就可以用单例。关键就在于类的使用方式都相同,并且不需要应用上下文。

工厂(Factory)模式

工厂模式提供一个通用的接口来创建对象。

例子:

function Car( options ) {
  this.doors = options.doors || 4;
  this.state = options.state || "brand new";
  this.color = options.color || "silver";
}

function Truck( options){
  this.state = options.state || "used";
  this.wheelSize = options.wheelSize || "large";
  this.color = options.color || "blue";
}

function VehicleFactory() {}
VehicleFactory.prototype.createVehicle = function ( options ) {
  switch(options.vehicleType){
    case "car":
      this.vehicleClass = Car;
      break;
    case "truck":
      this.vehicleClass = Truck;
      break;
    //defaults to VehicleFactory.prototype.vehicleClass (Car)
  }
  return new this.vehicleClass( options );
};
var carFactory = new VehicleFactory();
var car = carFactory.createVehicle( {
            vehicleType: "car",
            color: "yellow",
            doors: 6 } );
console.log( car instanceof Car ); // Outputs: true

何时使用工厂:

1. 当对象或组件设置非常复杂的时候。

2. 当需要根据所在的不同环境轻松生成对象的不同实例时。

3. 当处理很多共享相同属性的小型对象或组件时。

4. 对象的实例只需要满足一个约定——鸭子类型(duck typing)。利于解耦。

PS:鸭子类型——“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”我们并不关心对象是什么类型,到底是不是鸭子,只关心行为。

抽象工厂(Abstract Factory)模式

书中描述:

使用抽象工厂模式场景:一个系统必须独立于它所创建的对象的生成方式,或它需要与多种对象类型一起工作。

PS:我觉得没描述清楚。

网上定义:

为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。

PS:这个才比较清晰。

我的理解:

在工厂模式的加上一层抽象,工厂的工厂。

总结

单例模式和工厂模式概念上是比较简单,但是在使用上需要留心。该不该用单例,就考虑上面讲的单例三要点;该不该用工厂,就要看它是否带来大量不必要的复杂性,带来不必要的开销(不为了用模式而用模式)。抽象工厂模式并没有找到好的示例,就先略下。

另外越读这本书,越觉得在某些译文上有些问题,太过于直译,我觉得应该要结合理解做翻译,不然就像外国人讲普通话,太怪了。

参考文献

1. 《Learning JavaScript Design Patterns》 by Addy Osmani

https://addyosmani.com/resources/essentialjsdesignpatterns/book/

2. 《JavaScript设计模式》by 徐涛【译】

本文为原创文章,转载请保留原出处,方便溯源,如有错误地方,谢谢指正。

本文地址 :http://www.cnblogs.com/lovesong/p/5573521.html

时间: 2024-12-12 14:35:45

(四)单例模式与工厂模式的相关文章

常见的设计模式:单例模式、工厂模式、观察者模式、装饰模式与适配器模式

常见的设计模式:单例模式.工厂模式.观察者模式.装饰模式与适配器模式 这里可以阅读Terry Lee的设计模式系列来理解学习一下 1.4.1 单例模式 .NET设计模式(2):单件模式(Singleton Pattern)  http://terrylee.cnblogs.com/archive/2005/12/09/293509.html 1.4.2 抽象工厂模式 .NET设计模式(3):抽象工厂模式(Abstract Factory) http://terrylee.cnblogs.com/

PHP模式设计之单例模式、工厂模式、注册树模式、适配器模式、观察者模式

php模式设计之单例模式 什么是单例模式? 单例模式是指在整个应用中只有一个实例对象的设计模式 为什么要用单例模式? php经常要链接数据库,如果在一个项目中频繁建立连接数据库,会造成服务器资源的很大浪费,在团队合作项目中,也能够避免不同的程序员实例自己的对象,造成人为的系统消耗. 单例模式的三大原则 1.构造函数需要标记为非public(防止外部使用new操作符创建对象),单例类不能在其他类中实例化,只能被其自身实例化 2.拥有一个保存类的实例的静态成员变量$_instance 3.拥有一个可

前端设计模式——单例模式和工厂模式

作为一个前端新人,学习了设计模式以后,希望能从源头上,用浅显易懂的语言来解释它.当然不一定是正确的,只是我个人对设计模式的一点浅显理解. 创建型设计模式 创建型设计模式:故名思意,这些模式都是用来创建实例对象的. 单例模式:首先我们需要理解什么是单例.单:指的是一个.例:指的是创建的实例.单例:指的是创建的总是同一个实例.也就是使用类创建的实例始终是相同的.我们先看下面的一段代码: class Person{ constructor(){} } let p1 = new Person(); le

单例模式和工厂模式(百度文库)

模式中的单例模式分为:饿汉模式和懒汉模式. 顾名思义: 饿汉模式是对食物(Singleton)比较渴望的,所有一开始就new了一个来满足(食欲) 饿汉式: public class Singleton{   private static Singleton singleton = new Singleton ();   private Singleton (){}   public static  Singleton getInstance(){return singletion;}   } 饿

php面向对象单例模式、工厂模式及6大原则

一.单例模式目的:为了控制对象的数量(只能够有一个,相当于类的计划生育)做法1.将类的构造函数做成私有的2.在类里面做了一个公有的函数来造对象3.将该函数变为静态的4.在函数里面加控制 class Ren { public $name; static public $dx; //静态成员变量用来存储该对象 private function __construct() //把构造函数设置为私有,类的外部就不能用new造对象了 { } static function DuiXiang() //做一个

php单例模式与工厂模式

单例模式:单例模式又称为职责模式,它用来在程序中创建一个单一功能的访问点,通俗地说就是实例化出来的对象是唯一的. 所有的单例模式至少拥有以下三种公共元素:1. 它们必须拥有一个构造函数,并且必须被标记为private2. 它们拥有一个保存类的实例的静态成员变量3. 它们拥有一个访问这个实例的公共的静态方法 代码: <?php class ren { public $name; private static $dx;//存储对象 //声明一个私有的实例变量 private function __c

单例模式和工厂模式的简单理解

//什么是单例模式?//单例模式就是在核心就够中只包含一个被称作单例的特殊的类,通过单例模式可以保证系统中一个类只有一个实例,也就是说一个类只有一个对象实例using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApp1 { class danli { static void Main(s

java:常用的两种设计模式(单例模式和工厂模式)

一.单例模式:即一个类由始至终只有一个实例.有两种实现方式(1)定义一个类,它的构造方法是私有的,有一个私有的静态的该类的变量在初始化的时候就实例化,通过一个公有的静态的方法获取该对象.Java代码 1. //单例模式的第一种形式    2. public class Singleton01 {    3.    4.     // 私有的静态属性    5.     private static Singleton01 instance = new Singleton01();    6.  

php中的单例模式和工厂模式

单例模式又称为职责模式,它用来在程序中创建一个单一功能的访问点,通俗地说就是实例化出来的对象是唯一的. 所有的单例模式至少拥有以下三种公共元素: 1. 它们必须拥有一个构造函数,并且必须被标记为private 2. 它们拥有一个保存类的实例的静态成员变量 3. 它们拥有一个访问这个实例的公共的静态方法 单例类不能再其它类中直接实例化,只能被其自身实例化.它不会创建实例副本,而是会向单例类内部存储的实例返回一个引用. 示例: class Single { private $name;//声明一个私