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) ["精神小伙修炼手册", "摇花手", "豆豆鞋"] |

浙公网安备 33010602011771号