简单工厂
简单工厂通常是一个对象,对象中包含一些可以复用的方法,如果需要改动,只需要改动工厂中的方法就可以实现全部更新。
let BicycleFactory = {
createBicycle(model){
let bicycle = null;
switch(model){
case 'speeder':
bicycle = new Speeder();
break;
case 'Lowest':
bicycle = new Lowest();
break;
}
return bicycle;
}
}
工厂模式
工厂是一个将其成员对象的实例化推迟到子类中进行的类。
真正的工厂模式与简单的工厂模式的区别在于,工厂模式不使用一个对象,而是使用一个子类实现创建新实例的方法。
let BicycleShop = function () {
}
BicycleShop.prototype.sellBicycle = function () {
let bicycle = this.creatwBicycle(model);
bicycle.wash();
}
let AssmBicycleShop = function (){
}
AssmBicycleShop.prototype.createBicycle = function (model) {
let bicycle = null;
switch(model){
case 'speeder':
bicycle = new Speeder();
break;
}
return bicycle;
}
父类中的公共方法需要使用一个对象进行操作,这个对象的创建应该由子类创建。
function Animal() {
}
Animal.prototype.prototype.talk = function () {
let dog = this.createDog();
dog.talk();
}
function Dog() {
}
Dog.prototype.createDog = function (model) {
let dog = null;
switch(model){
case 'gray':
dog = new Gray();
break;
}
return dog;
}
Dog.prototype.talk = function () {
console.log("wang");
}
Dog类需要继承Animal类。
父类或构造器要实现公共的方法。
用工厂模式创建XHR对象
function XHRFactory() {
}
XHRFactory.prototype.createXhrObect = function () {
let methods = [
function () {return new XMLHttpRequest()},
function () {return new ActiveXObject('Msxml2.XMLHttp')},
function () {return new ActiveXObject('Miscrosoft.XMLHttp')}
];
for(let i = 0; i < methods.length; i++) {
try{
methods[i]();
}catch{
continue;
}
this.createXhtObject = methods[i];
return methods[i]();
}
}
XHRFactory.prototype.request = function (success, fail) {
let xhr = this.createXhrObject();
xhr.onreadystatechange = function () {
if(xhr.stete === 4 && xhr.status === 200){
success(xhr.reposneText);
} else {
fail(xhr.status);
}
}
}
第二次执行request时createXhtObject就变成了
createXhrObject = function () {
return new XMLHttpRequest();
}
根据不同浏览器的实现发生变化。
抽象工厂模式
通过对类的工厂抽象使其业务用于对产品类簇的创建,而不负责创建某一类产品的实例。
// 抽象类,用于创建子类
function Person(name, age) {
this.name = name;
this.age = age;
Person.prototype.getName = function () {
throw new Error('抽象方法不能被调用');
}
Person.prototype.getAge = function () {
throw new Error('抽象方法不能被调用');
}
}
// 抽象工厂,创建的不是一个具体的实例,而是一个类簇,规定了该类对象的结构
function AbstractFactory(subType, superType) {
if (typeof AbstractFactory[superType] === 'function') {
function fn() {}
fn.prototype = new AbstractFactory[superType]();
subType.prototype = new fn();
}
}
AbstractFactory.Person = Person;
// 基类,用于创建具体的对象实例
function Student(name, age){
this.name = name;
this.age = age;
}
Student.prototype.getName = function () {
return this.name;
}
Student.prototype.getAge = function(){
return this.age;
}
AbstractFactory(Student, 'Person');
let liming = new Student();
liming.getName();
liming.getAge();
工厂模式的适用场合
动态实现
不同方式实现统一接口的对象,使用工厂方法简化选择的过程。这种选择可以是明确的,也可以是隐含的。
节省设置开销
如果对象需要复杂并且彼此相关的设置,那么工厂模式可以减少每种对象所需的代码量。
用许多小型对象组合成一个大对象
工厂方法可以用来创建封装了许多小对象的对象。
function Display(listDisplay, fieldsetDisplay, config){
this.listDisplay = listDisplay;
this.fieldsetDisplay = fieldsetDisplay;
this.config = config;
}
function ListDisplay(list){
this.list = list;
}
function FieldsetDisplay(fieldset) {
this.fieldset = fieldset;
}
let config = {
id:'root',
updateInterval:60
}
let displayManager = {
createDisplayer(){
let listDisplay = new ListDisplay();
let fieldsetDisplay = new FieldsetDisplay();
return new Display(listDisplay, fieldsetDisplay, config);
}
}
displayManager 先创建所需要的其他对象,然后将这些对象传递给 Display 生成一个包含这些对象的大对象。
优缺点
优点
- 消除对象间的耦合
- 在派生子类时提供了更大的灵活性
可以先创建一个抽象的父类,在子类中创建工厂方法,这样可以把实例化推迟到专门化的子类中
缺点
-
容易被滥用
工厂函数可以把具体的实现进行封装,容易把工厂模式当成万金油,用其取代构造函数。
如果不需要在运行期间在多个类之间进行选择,就不要使用工厂模式。 -
隐藏具体的对象构造
由于工厂函数把对象的实例化过程进行封装,有时需要查看代码才能知道实例化的是什么类。
1396

被折叠的 条评论
为什么被折叠?



