文:阿蜜果/2011-11-8
转载请注明出处
工厂设计模式是面向对象编程中最常用的设计模式之一。它又被称为创建性模式,因为它被用来创建其他类。在应用程序预见不到自己要创建的对象类型时,就会使用工厂解决方案。在这些情况下,可以使用工厂模式作为创建对象的基础,不需要确切地了解将要创建哪些对象。
根据工厂模式实现的类可根据提供的数据生成一组类中某一个类的实例,通常这一组类有一个公共的抽象父类并且实现了相同的方法,但是这些方法针对不同的数据进行了不同的操作。
首先需要定义一个基类,该类的子类通过不同的方法实现了基类中的方法。然后需要定义一个工厂类,工厂类可以根据条件生成不同的子类实例。当得到子类的实例后,开发人员可以调用基类中的方法而不必考虑到底返回的是哪一个子类的实例。
工厂模式的示意图如下所示:
在上面的图形中,Client需要的Product对象不再通过new Product(…)来生成,而是通过工厂类Factory类的creates方法来获取,工厂类一般提供多种有相关关系的对象的生成,用于解除Client类对Product类的直接耦合关系。
工厂模式常见的应用场合如下:
(1)动态实现:例如在玩“极品飞车”这款游戏时,游戏者可以根据不同品牌选择赛车,而这个“品牌”其实就是工厂,每个工厂生产的赛车都不一样,这就是典型的工厂方法的应用场景。可以创建一些用不同方式实现同一接口的对象,那么可以使用一个工厂方法或简单工厂对象来简化选择所采用的实现的过程。
(2)节省设置开销:如果对象需要进行复杂而且彼此相关的设置,那么使用工厂模式可以减少减少每种对象所需的代码量。如果这种设置只需要为特性类型的所有实例执行一次即可,这种作用尤其突出。把这种设置代码放在类的构造器函数中并不是一种高效的做法。这是因为即便设置工作已经完成,每次创建新实例的时候这些代码还是会执行,而且这样做会把设置代码分散在不同的类中。
(3)用许多小型对象组成一个大对象:工厂方法用来创建封装了许多较小对象的对象。例如自行车包含了许多更小的子系统:车轮、车架、传动部件以及车闸等。如果不想让某个子系统与较大的对象之间形成强耦合,而是想在运行时从许多子系统中进行挑选的话,那么工厂模式是一个很好的选择。
在JavaScript中,单例(Singleton)模式是最基本又最有用的模式之一。这种模式提供了一种将代码组织为一个逻辑单元的手段,这个逻辑单元中的代码可以通过单一的变量进行访问。确保单例对象只有一份实例,你就可以确信自己的所有代码使用的都是同样的全局资源。
单例类在JavaScript中用途广泛:
(1)可以用来划分命名空间,以减少网页中全局变量的数量;
(2)可以在一种名为分支的技术中用来封装浏览器之间的差异;
(3)可以借助于单例模式,将代码组织得更为一致,从而使代码更容易阅读和维护。
假设你想开一个自行车商店,每个店都有几个型号的自行车出售。
首先创建一个BicycleFactory类,该类的createBicycle用于根据传入的不同的类型时创建不同的自行车对象,该类的代码如下:
在如上代码中,createBicycle方法根据所要求自行车型号用switch创建一个自行车的实例,各种型号的自行车实例可以互换使用,因为都实现了Bicycle接口。
若Bicycle接口的定义如下所示(包括assemble、wash、ride和repair四个方法):
下面示意一下实现了Bicycle接口的Speedster:
接着创建一个自行车商店类,该类包含一个sellBicycle(销售自行车)的方法,该方法首先通过工厂类的createBicycle方法获得一辆自行车,接着对自行车进行组装和清洗:
若要出售一辆Speedster类型的自行车,参考代码如下:
BicycleFactory就是简单工厂的一个很好的实例。这种模式把成员对象的创建工作转交给一个外部对象。如果负责创建实例的方法的逻辑不会发生变化,那么一般说来使用单例或静态方法创建这些成员实例都是合理的,但如果需要提供几种不同品牌的自行车,那么更恰当的做法是把这些创建方法实现在一个类中,并从该类派生出一个子类。
待写。
在JavaScript中使用工厂模式的主要优点如下:
(1)弱化对象间的耦合;
(2)通过工厂方法而不是new关键字及具体类,可以把所有实例化代码集中在一个位置,这可以大大简化更换所用的类或运行期间动态选择所用的类的工作;
(3)防止代码的重复:在一个类中进行类的实例化,可以消除重复性的代码。
不适合使用的场合为:
如果根本不可能另外换用一个类,或者不需要在运行期间在一系列可互换的类中进行选择,那么不应该使用工厂方法,使用构造函数进行公开的实例化即可,因为这可以一眼看出调用的是什么构造函数,而不必去查看某个工厂方法以便知道实例化的是什么类。
(1)《JavaScript设计模式》 Ross Harmes,Dustin Dial著,谢廷晟 译,人民邮电出版社出版
(2)《工厂模式_百度百科》:
http://baike.baidu.com/view/1306799.htm
(3)《工厂模式UML图》:
http://apps.hi.baidu.com/share/detail/31694688