Javascript:设计模式-简单工厂模式

工厂模式大体分为三类:简单工厂模式、工厂方法模式、抽象工厂模式。

在我们日常的实现功能逻辑中,最基础的一种方法是这样的:

有一个体育器材店,每一种类型的运动器材都有名称和简介。以篮球为例:

1
2
3
4
5
6
7
var Basketball = function () {
  this.info='篮球';
}
Basketball.prototype = {
  getMem : function(){ console.log('每个队伍需要5个人') }
  getSize: function(){console.log('篮球尺寸很大')}
}
当你拿到一个球,你会看到这样的信息
1
2
3
4
var ball = new Basketball()
ball.info //"篮球"
ball.getMem() //每个队需要5个人
ball.getSize() //篮球尺寸很大

介于店里各种各样的商品,你看花了眼,每一个都得拿起来看,看完再放回去。(重复创建好多实例去执行代码实现你的需求)

原理:声明对象,后续给对象加属性和方法

优点:可以直观的看出对象Basketball有属性info,方法getMem、getSize;

缺点:如果有多个类型,需要创建多个实例;

 

这时候你会怎么想?是不是会想到 ,假如有个人能帮我拿多好! 这时候店铺老板刚好看到了你,急忙走过来问你:同学 想了解什么样的器材,我可以帮你呀。这下你就方便多了,每说出一个类型,老板就能快速的帮你找到这类器材。

 注意这里:你和老板的区别,你是一个一个去拿起来看,而老板则是自己的店铺,知道你要的类型的摆放在哪里,明显效率很多。

接着你就明白了,你不需要自己回忆那么多器材的特征,样式,尺寸,颜色等等。。 你只需要告诉老板 你要的器材叫什么名字,他就可以帮你找到!

类比到JavaScript中。这就是简单工厂模式

 

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
var Basketball = function () {
  this.info='篮球';
}
Basketball.prototype = {
  getMem : function(){ console.log('每个队伍需要5个人') }
  getSize: function(){console.log('篮球尺寸很大')}
}
var Football = function () {
  this.info='足球';
}
Football.prototype = {
  getMem : function(){  console.log('每个队伍需要11个人') }
  getSize: function(){console.log('足球尺寸很大')}
}
var Tennis= function () {
  this.info='网球';
}
Tennis.prototype = {
  getMem : function(){ console.log('每个队伍需要1个人') }
  getSize: function(){console.log('网球很大')}
}
//创建工厂类囊括上面的三种基类
var SportFactory= function(name){
    switch(name){
     case 'NBA':
        return new Basketball();
     case 'wordCup':
        return new Football ();
     case 'frenchOpen':
        return new Tennis();
    default:
       throw new Error('没有您需要的器材')
 }
}

当你和小伙伴想踢球,只需要告诉店员你想买个球,使用这个工厂时仅需记住SportFactory这个工厂对象就好了。

 

1
2
3
4
5
6
var football = SportFactory('wordCup');
console.og(football);
console.log(football.intro);
football.getMem();
var basketball =  SportFactory('NBA');
var tennis =  SportFactory('frenchOpen');

优点:
可以免除直接创建产品对象实例的责任,而仅仅是“消费”产品。简单工厂模式通过这种做法实现了对责任的分割
缺点:
由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则;
这种做法扩展性差,违背了开闭原则,也影响了可读性。
所以,这种方式使用在业务较简单,工厂类不会经常更改的情况。

 

简单工厂 模式===>工厂方法模式。

我来到一家书店买书,我要买编程类的书,分别是“JS高级编程,第三版,2013年出版”、“CSS世界,第一版,2017年出版”、“VUE权威指南,第一版,2018年出版”,我不用自己去找这些书,而是口头告诉给店员,让他帮我找,并且告诉我价格。

这时,店员就是这个简单工厂对象,而返回给我的书的信息以及价格则是这个产品的实例。:

function bookShop (name, year, vs) {
  var book = new Object();
  book.name = name;
  book.year = year;
  book.vs = vs;
  book.price = '暂无标价';
  if (name === 'JS高级编程') {
    book.price = '79';
  }
  if (name === 'css世界') {
    book.price = '69';
  }
  if (name === 'VUE权威指南') {
    book.price = '89';
  }
  return book;
}
var book1 = bookShop('JS高级编程''2013''第三版');
var book2 = bookShop('ES6入门教程''2017''第六版');
var book3 = bookShop('css世界''2015''第一版');
console.log(book1) //{name: "JS高级编程", year: "2013", vs: "第三版", price: "79"}
console.log(book2) //{name: "ES6入门教程", year: "2017", vs: "第六版", price: "暂无标价"}
console.log(book3) //{name: "css世界", year: "2015", vs: "第一版", price: "69"}

工厂方法模式是对产品类的抽象,使其创建多类产品的实例。

上面简单工厂模式是创建同一类的某个产品,而这里的工厂方法模式是创建多类产品的实例,区别就出来了,它其实是将多个产品类进行抽象化,可以通过这个工厂对这些类创建相应类的实例。

比如现在,我不想买编程类的书了,我要买科学类或者社会学类的书,那么工厂方法模式的作用就体现出来了。

var BookShop = function (name) {
  // 如果外部直接调用了BookShop而不是new关键字调用,则返回new BookShop调用,否则直接调用
  // 这个产品类创建实例返给外部
  if (this instanceof BookShop) {
    var book = new this[name]()
    return book
  else {
    return new BookShop(name)
  }
}
BookShop.prototype = {
  Programme: function () {
    this.books = ['css世界''JS高级编程''ES6入门教程']
  },
  Science: function () {
    this.books = ['人与自然''大自然的奥秘''走进科学']
  },
  Society: function () {
    this.books = ['精神小伙修炼手册''摇花手''豆豆鞋']
  }
}
 
var programme = new BookShop('programme');
var science = BookShop('science');
var society = BookShop('society');
console.log(programme) // books: (3) ["css世界", "JS高级编程", "ES6入门教程"]
console.log(science) // books: (3) ["人与自然", "大自然的奥秘", "走进科学"]
console.log(society) // books: (3) ["精神小伙修炼手册", "摇花手", "豆豆鞋"]

 

posted on 2022-08-25 09:58  紫叶嵋  阅读(80)  评论(0编辑  收藏  举报