当前位置:   article > 正文

JavaScript设计模式-工厂模式_工厂模式javascript

工厂模式javascript

简单工厂

简单工厂通常是一个对象,对象中包含一些可以复用的方法,如果需要改动,只需要改动工厂中的方法就可以实现全部更新。

let BicycleFactory = {
	createBicycle(model){
	let bicycle = null;
		switch(model){
			case 'speeder':
				bicycle = new Speeder();
				break;
			case 'Lowest':
				bicycle = new Lowest();
				break;
		}
		return bicycle;
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

工厂模式

工厂是一个将其成员对象的实例化推迟到子类中进行的类。
真正的工厂模式与简单的工厂模式的区别在于,工厂模式不使用一个对象,而是使用一个子类实现创建新实例的方法。

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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

父类中的公共方法需要使用一个对象进行操作,这个对象的创建应该由子类创建。

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");
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

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);
		}
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

第二次执行request时createXhtObject就变成了

createXhrObject = function () {
	return new XMLHttpRequest();
}
  • 1
  • 2
  • 3

根据不同浏览器的实现发生变化。

抽象工厂模式

通过对类的工厂抽象使其业务用于对产品类簇的创建,而不负责创建某一类产品的实例。

// 抽象类,用于创建子类
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();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

工厂模式的适用场合

动态实现

不同方式实现统一接口的对象,使用工厂方法简化选择的过程。这种选择可以是明确的,也可以是隐含的。

节省设置开销

如果对象需要复杂并且彼此相关的设置,那么工厂模式可以减少每种对象所需的代码量。

用许多小型对象组合成一个大对象

工厂方法可以用来创建封装了许多小对象的对象。

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);
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

displayManager 先创建所需要的其他对象,然后将这些对象传递给 Display 生成一个包含这些对象的大对象。

优缺点

优点

  1. 消除对象间的耦合
  2. 在派生子类时提供了更大的灵活性
    可以先创建一个抽象的父类,在子类中创建工厂方法,这样可以把实例化推迟到专门化的子类中

缺点

  1. 容易被滥用
    工厂函数可以把具体的实现进行封装,容易把工厂模式当成万金油,用其取代构造函数。
    如果不需要在运行期间在多个类之间进行选择,就不要使用工厂模式。

  2. 隐藏具体的对象构造
    由于工厂函数把对象的实例化过程进行封装,有时需要查看代码才能知道实例化的是什么类。

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/神奇cpp/article/detail/844912
推荐阅读
相关标签
  

闽ICP备14008679号