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) ["精神小伙修炼手册", "摇花手", "豆豆鞋"] |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器