前端常见的8种设计模式,前端学习者的福音!!
在前端开发中,设计模式是一种被广泛应用的思想。设计模式可以帮助开发者解决常见的问题,并提供可重用的解决方案。本文将会介绍前端常见的设计模式,并通过代码详解它们的实现。
一、单例模式
单例模式是指一个类只能被实例化一次,并提供全局访问点。这个模式非常适合那些需要共享资源的场景。比如,在前端开发中,我们经常需要确保某些资源只被加载一次,而不是每次都重新加载。下面是一个使用单例模式的例子:
(资料图)
class Singleton { constructor() { if (typeof Singleton.instance === 'object') { return Singleton.instance; } this.name = 'Singleton'; Singleton.instance = this; return this; }}const instance1 = new Singleton();const instance2 = new Singleton();console.log(instance1 === instance2); // true
上述代码中,我们创建了一个 Singleton 类,该类只能被实例化一次。如果多次尝试实例化该类,将会返回同一个实例。这样就保证了某些资源只会被加载一次,从而提高性能。
二、观察者模式
观察者模式是指当一个对象状态改变时,它的所有依赖者都会收到通知并自动更新。这个模式非常适合那些需要实时更新用户界面的场景。下面是一个使用观察者模式的例子:
class ObserverList { constructor() { this.observerList = []; } add(observer) { return this.observerList.push(observer); } remove(observer) { this.observerList = this.observerList.filter((obs) => obs !== observer); } count() { return this.observerList.length; } get(i) { return this.observerList[i]; }}class Subject { constructor() { this.observers = new ObserverList(); } addObserver(observer) { this.observers.add(observer); } removeObserver(observer) { this.observers.remove(observer); } notify(context) { const observerCount = this.observers.count(); for (let i = 0; i < observerCount; i++) { this.observers.get(i).update(context); } }}class Observer { constructor() { this.update = () => {}; }}const subject = new Subject();const observer1 = new Observer();observer1.update = function (context) { console.log(`Observer 1: ${context}`);};const observer2 = new Observer();observer2.update = function (context) { console.log(`Observer 2: ${context}`);};subject.addObserver(observer1);subject.addObserver(observer2);subject.notify('Hello World');
上述代码中,我们创建了一个 Subject 类和一个 Observer 类。Subject 类包含了一个观察者列表,并提供了添加、删除和通知观察者的方法。Observer 类则包含了一个更新方法,用于处理来自被观察者的通知。在主程序中,我们创建了两个观察者,并将它们添加到被观察者的观察者列表中。然后,我们通知被观察者,被观察者会自动通知所有观察者,并执行它们的更新方法。
三、工厂模式
工厂模式是指通过一个工厂类来创建其他类的实例。这个模式非常适合那些需要根据不同条件创建不同实例的场景。下面是一个使用工厂模式的例子:
class ProductA {constructor(name) {this.name = name;}operation() {console.log(`Product A (${this.name}) is working.`);}}class ProductB {constructor(name) {this.name = name;}operation() {console.log(`Product B (${this.name}) is working.`);}}class Factory {createProduct(type, name) {switch (type) {case 'A':return new ProductA(name);case 'B':return new ProductB(name);default:throw new Error('Invalid product type.');}}}const factory = new Factory();const productA1 = factory.createProduct('A', 'productA1');const productA2 = factory.createProduct('A', 'productA2');const productB1 = factory.createProduct('B', 'productB1');const productB2 = factory.createProduct('B', 'productB2');productA1.operation(); // Product A (productA1) is working.productA2.operation(); // Product A (productA2) is working.productB1.operation(); // Product B (productB1) is working.productB2.operation(); // Product B (productB2) is working.
上述代码中,我们创建了两个产品类 `ProductA` 和 `ProductB`,以及一个工厂类 `Factory`。工厂类提供了一个创建产品实例的方法 `createProduct`,该方法根据传入的参数来决定创建哪种产品实例。在主程序中,我们通过工厂类创建了四个不同的产品实例,并分别执行它们的操作方法。
四、装饰者模式
装饰者模式是指动态地给一个对象增加一些额外的功能。这个模式非常适合那些需要在运行时动态改变对象行为的场景。下面是一个使用装饰者模式的例子:
class Shape {draw() {}}class Circle extends Shape {draw() {console.log('Drawing a circle.');}}class Rectangle extends Shape {draw() {console.log('Drawing a rectangle.');}}class Decorator {constructor(shape) {this.shape = shape;}draw() {this.shape.draw();}}class RedShapeDecorator extends Decorator {draw() {this.shape.draw();this.setRedBorder();}setRedBorder() {console.log('Setting red border.');}}const circle = new Circle();const rectangle = new Rectangle();circle.draw(); // Drawing a circle.rectangle.draw(); // Drawing a rectangle.const redCircle = new RedShapeDecorator(new Circle());const redRectangle = new RedShapeDecorator(new Rectangle());redCircle.draw(); // Drawing a circle. Setting red border.redRectangle.draw(); // Drawing a rectangle. Setting red border.
上述代码中,我们创建了两个形状类 Circle 和 Rectangle,以及一个装饰者类 Decorator。装饰者类包含了一个形状对象,用于对其进行装饰。然后,我们创建了一个红色形状装饰者类 RedShapeDecorator,用于在形状周围添加一个红色边框。在主程序中,我们先执行原始形状的绘制方法,然后再使用红色装饰器对其进行装饰。
五、代理模式
代理模式是指使用一个代理对象来控制对另一个对象的访问。这个模式非常适合那些需要控制对某些敏感资源的访问的场景。下面是一个使用代理模式的例子:
class Image { constructor(url) { this.url = url; this.loadImage(); } loadImage() { console.log(`Loading image from ${this.url}`); }}class ProxyImage { constructor(url) { this.url = url; } loadImage() { if (!this.image) { this.image = new Image(this.url); } console.log(`Displaying cached image from ${this.url}`); }}const image1 = new Image('https://example.com/image1.jpg');const proxyImage1 = new ProxyImage('https://example.com/image1.jpg');proxyImage1.loadImage(); // Loading image from https://example.com/image1.jpgproxyImage1.loadImage(); // Displaying cached image from https://example.com/image1.jpgconst image2 = new Image('https://example.com/image2.jpg');const proxyImage2 = new ProxyImage('https://example.com/image2.jpg');proxyImage2.loadImage(); // Loading image from https://example.com/image2.jpgproxyImage2.loadImage(); // Displaying cached image from https://example.com/image2.jpg
上述代码中,我们创建了一个图片类 `Image` 和一个代理图片类 `ProxyImage`。代理图片类包含了一个图片对象,用于控制对其加载和显示的访问。在主程序中,我们首先创建了一个真实的图片对象,并使用代理图片对象进行访问。第一次访问时,代理图片对象会加载并显示真实的图片;第二次访问时,代理图片对象直接从缓存中获取并显示图片。
六、适配器模式
适配器模式是指将不兼容接口的对象转化为兼容接口的对象。这个模式非常适合那些需要改变接口而不影响原有代码的场景。下面是一个使用适配器模式的例子:
class OldCalculator { operations(a, b, operation) { switch (operation) { case 'add': return a + b; case 'sub': return a - b; default: return NaN; } }}class NewCalculator { add(a, b) { return a + b; } sub(a, b) { return a - b; }}class CalculatorAdapter { constructor() { this.newCalculator = new NewCalculator(); } operations(a, b, operation) { switch (operation) { case 'add': return this.newCalculator.add(a, b); case 'sub': return this.newCalculator.sub(a, b); default: return NaN; } }}const oldCalculator = new OldCalculator();console.log(oldCalculator.operations(10, 5, 'add')); // 15const newCalculator = new NewCalculator();console.log(newCalculator.add(10, 5)); // 15const calculatorAdapter = new CalculatorAdapter();console.log(calculatorAdapter.operations(10, 5, 'add')); // 15
上述代码中,我们创建了一个旧计算器类 OldCalculator 和一个新计算器类 NewCalculator。然后,我们创建了一个适配器类 CalculatorAdapter,该类包含了一个新计算器对象,用于将旧计算器的操作转化为新计算器的操作。在主程序中,我们分别使用旧计算器、新计算器和适配器进行加法运算,并得到了相同的结果。
七、命令模式
命令模式是指将请求封装成一个对象,并提供与执行该请求相关的所有信息。这个模式非常适合那些需要执行多个不同操作的场景。下面是一个使用命令模式的例子:
class Receiver { run() { console.log('Receiver is running.'); }}class Command { constructor(receiver) { this.receiver = receiver; } execute() {}}class StartCommand extends Command { execute() { this.receiver.run(); }}class Invoker { setCommand(command) { this.command = command; } executeCommand() { this.command.execute(); }}const receiver = new Receiver();const startCommand = new StartCommand(receiver);const invoker = new Invoker();invoker.setCommand(startCommand);invoker.executeCommand(); // Receiver is running.
上述代码中,我们创建了一个接收者类 Receiver 和一个命令基类 Command。然后,我们创建了一个具体命令类 StartCommand,该类继承自命令基类,并实现了执行方法 execute,用于启动接收者。最后,我们创建了一个调用者类 Invoker,该类包含了一个命令对象,并提供了执行命令的方法。在主程序中,我们创建了一个接收者对象、一个具体命令对象和一个调用者对象,并将具体命令对象设置为调用者对象的命令。然后,我们执行调用者对象的执行方法,该方法会调用具体命令对象的执行方法,从而启动接收者。这个例子比较简单,但命令模式可以应用于很多复杂的场景,例如撤销/恢复操作、事务管理等。
八、观察者模式
观察者模式是指在对象之间定义一种一对多的依赖关系,使得每当一个对象改变状态时,所有依赖于它的对象都会得到通知并自动更新。这个模式非常适合那些需要在应用中实现事件处理的场景。下面是一个使用观察者模式的例子:
class Subject { constructor() { this.observers = []; } addObserver(observer) { this.observers.push(observer); } removeObserver(observer) { const index = this.observers.indexOf(observer); if (index >= 0) { this.observers.splice(index, 1); } } notifyObservers() { for (const observer of this.observers) { observer.update(this); } }}class ConcreteSubject extends Subject { constructor(state) { super(); this.state = state; } getState() { return this.state; } setState(state) { this.state = state; this.notifyObservers(); }}class Observer { update() {}}class ConcreteObserver extends Observer { update(subject) { console.log(`The subject has changed to ${subject.getState()}.`); }}const subject = new ConcreteSubject('state1');const observer1 = new ConcreteObserver();const observer2 = new ConcreteObserver();subject.addObserver(observer1);subject.addObserver(observer2);subject.setState('state2'); // The subject has changed to state2.
上述代码中,我们创建了一个主题基类 Subject
和一个具体主题类 ConcreteSubject
。主题类包含了一个状态属性和一组观察者对象,并提供了方法以添加、删除和通知观察者。然后,我们创建了一个观察者基类 Observer
和一个具体观察者类 ConcreteObserver
,该类继承自观察者基类,并实现了更新方法。在主程序中,我们创建了一个具体主题对象、两个具体观察者对象,并将观察者对象添加到主题对象中。然后,我们修改了主题对象的状态,并通过主题对象通知观察者对象进行更新操作。
以上就是八种常见的设计模式以及它们的应用场景和示例代码。当然,这只是冰山一角,还有很多其他的设计模式可以应用于不同的场景。熟悉各种设计模式并且能够灵活运用它们可以让你成为更优秀的开发者。
今天的分享就到这里,感谢你的阅读,希望能够帮助到你,
文章创作不易,如果你喜欢我的分享,别忘了点赞转发,让更多有需要的人看到,最后别忘记关注UP主,你的支持将是我分享最大的动力,后续我会持续输出更多内容,敬请期待
同时准备了丰厚的学习资料来帮助大家的学习 需要的小伙伴找找up主领取即可
up主不主动联系大家哦~需要的小伙伴后台打招呼即可
标签:
- 前端常见的8种设计模式,前端学习者的福音!!
- 陕西榆林:陕西省人大常委会组团到院调研
- 每日视讯:全国工商联人才中心产教融合基地落户娄职
- 【茶茶】2K游戏新标杆?微星 RTX 4070 魔龙测试报告|世界即时看
- 中国篮协:消极比赛属实 上海久事与江苏肯帝亚被取消本赛季参赛资格
- 马迹山港矿石加工中心成功试生产运行|当前看点
- 桂香书屋“开门迎客” “桂香书屋”匾额冯其庸题写 全球新资讯
- 科思创将中国创新带向全球
- 【独家】三种颜色混合变色表 颜色混合变色表
- 世界消息!Spring Cloud Task 任务开发-定义任务输入和输出(一)
- 如何避免茂名美术培训机构的坑? 讯息
- 天天快看:奥迪Q8更新,78.28万元起,要不起可以说不好看
- 《南方》杂志社论:高擎思想之旗,坚定走在前列
- 华海药业:预计2023年1-3月盈利,净利润同比增15%至38% 重点聚焦
- 空心草莓是打了激素?“个大”的草莓是因为打了药?解答来了
- 环球焦点!五一出游搭配指南,12套休闲风穿搭舒适减龄,穿出不费力的时髦感
- 好汉歌英文版歌词音译_好汉歌英文版歌词_世界新要闻
- 热文:取胜功臣!哈特身穿一件印有布伦森封面写真的T恤出席赛后发布会
- 钟丽缇深夜连麦张伦硕再度委屈痛哭:我先生比我小12岁又怎样? 环球速读
- 浙江海边哪里好玩_好玩的地方推荐
- 计算机网络的定义和功能分别是什么_计算机网络的定义 分类和主要功能是什么|环球播资讯
- 崇信县2家合作社被评为第六批省级农民合作社示范社
- 环球热消息:前米兰主帅萨基认为迈尼昂作用关键,AC米兰发挥了半场欧冠水平
- 广汽本田经销商门店被曝资金困难,本田不至于吧?
- 送40岁男人礼物排行榜
- 长城的成语组词_长城的成语
- 天天最新:伟星股份:越南工业园一期项目主体厂房近期已顺利结顶
- 今日讯!日媒曝光图片:传出爆炸声后,岸田文雄在安保人员簇拥下离开现场
- 全球视点!给人倒酒时,最忌讳“祭祀手”,这是为什么?建议搞懂以免得罪人
- 2023年新年第一天发朋友圈的祝福语(4篇)
- 北京师范大学举行国家安全主题宣讲活动
- 或运算c语言_或运算-热点
- “末日博士”鲁比尼:美联储双重使命变三重 已成“不可能的任务”|环球时讯
- 该死的英文怎么写_该死的英文-天天热点
- 新联电子: 2022年年度报告摘要|微头条
- 热议:汽车发动机排行榜前十 汽车发动机排行榜
- 【当前独家】重庆图书馆首个列车书屋正式建成开放
- 大V代客理财 ,多人巨亏!宝妈300万买房款几近亏光!当事人详述“惨剧”始末……_热头条
- 全球要闻:北京警方:2022年侦办网络犯罪2700余件 关停违规账号180余万个
- 世界视点!完美世界:一季度净利润预降69.06%–73.82%
- 全球热头条丨如果说你若成佛是什么歌 如果说你若成佛
- 今日快讯:上半年演唱会市场票房规模将达30亿,购票人次较疫情前大幅提升
- 特朗普向“封口费”经手人索赔5亿美元 焦点
- 柳州连垃圾桶也要火了?网友:是我不懂潮流!_天天热消息
- 蝉与鸲鹆翻译_蝉与鸲鹆-天天视讯
- 国际货币基金组织:全球金融稳定风险迅速上升_最新快讯
- Hystrix请求合并的使用(二)_全球微动态
- 环球新动态:四大行或最快6月发行TLAC债券
- 益路同行、爱心汇聚——助力双峡村“湘妹子能量家园”积分超市建设
- 全球信息:沪深港通标的扩容满月,互联互通机制持续深化
- “五一”假期临近 重庆热度居全国前列-环球热点
- 笃行创变,2023捷途之夜见证“旅行+”的持续迭代
- 山西博物院藏品概览·瓷器卷1
- 世界球精选!霍福德:季后赛我们的防守必须提升 罗威的成熟超过了他的年龄
- 滨江集团: 2023年度第二期短期融资券发行结果公告|最资讯
- 潘淦获批出任恒邦财险董事长|环球通讯
- 我为群众办实事丨市民担心行道树箅子影响树木生长 西安市城管局回应_快看
- 实控人父子内斗不休,两名独董又辞职,电科院收深交所关注函 全球新消息
- 留洋+4次转会被阻止!23岁国足第一中场无助,中超元年冠军太霸道
- 股票变成st之后要怎么处理
- 南山集团7亿元公司债将于4月19日兑付并摘牌 利率5.5%|精彩看点
- 半角阿拉伯数字怎么弄_半角宋体阿拉伯数字怎么设置
- 斗罗大陆H5疾风双头狼魂环搭配
- 秒无!国安首轮主场散票,开售不到5分钟被抢购一空
- @太原人!事关婚俗改革!山西一地发出倡议书|要闻速递
- 派奖正火热,责任要牢记,深圳体彩开展责任彩票专题培训
- 宜信博诚保险上海分公司违法被罚 未按规定用银行账户
- 4月13日生意社醋酸乙酯基准价为6766.67元/吨
- 怎么用烤箱做小面包_怎样用家用烤箱烤面包
- 把每位乘客平安送达目的地(守望)
- 【世界新视野】word如何检查错别字_word错别字检查
- 世界要闻:中植未了局:巨额罚款纷纷袭来 踩雷15家房企困境难解
- 全球播报:媒体人用平板有哪些体验?实现无纸化,提高生产力都是好帮手!
- 错付2万元出租车费的乘客终于找到 “的哥”说能睡个好觉了
- 山东省生态环境厅召开入海河流总氮治理专项行动3月份工作情况调度会
- 习近平在视察南部战区海军时强调 深化练兵备战 加快转型建设 全面提高部队现代化水平-天天微资讯
- 全球快消息!济宁五一去哪儿玩?
- 云南芒市:民族风情点燃边城“夜经济”
- 警方回应小伙扶摔倒老人被要求赔偿:小伙下楼时看向别处撞倒了老人-焦点速讯
- 政策引导数字经济加速发展 | 数字未来发展报告分析 全球聚焦
- 疯狂动物园(内置功能菜单)-焦点速讯
- 全球最资讯丨孟晚舟当值后,华为首个重磅会议来了!
- 4月12日内蒙汇能液化天然气价格动态
- 【热闻】多地省委书记深入一线密集调研:暗访路边摊、穿牛仔裤下基层
- 韩在野党党首:难排除美国监听 属实将敦促美方道歉
- 环球即时看!尼日利亚东南部134名平民遭武装分子杀害
- 环球快讯:聚光科技股东因未及时披露公司重大事件被深圳证券交易所采取监管措施
- 全球今日讯!据说,漫威电影《永恒族》将会有更多演员加入!
- 法国经济部长:欧洲应实现“思考自主”
- 4月11日基金净值:广发趋势优选灵活配置混合A最新净值1.6836,涨0.04% 全球速递
- 天天微头条丨“希望大家收获阳光和自信”——专访七人制特奥融合国足主教练陈芳芳
- 天津医护类院校排名 天津大学往年的最低录取分数线是多少?-天天速递
- 全球滚动:民宿康养中医药——看康养咸安的“吉祥三宝”
- 未客观、完整反映新能源电池产业园105亿元总投资的构成等 雄韬股份及董事长等收深圳证监局警示函-天天热消息
- 绥宁县和邵阳县开展森林防火工作经验交流
- 不敌“少子化”冲击 台北市创立逾50年私立中学确定停招
- 全球视讯!任职2年多回报负38%,农银基金梦圆发新基,投资者会买单吗?
- 汪小菲台北酒店更名,疑因大S索要天价代言费,网友:欺人太甚_天天观天下
- 日本半导体制造设备的销售额已连续5个月环比下滑|世界微动态
- 真“刑”!资阳市雁江区一男子醉驾撞伤4人 每日消息
广告
广告
- 如何验证翡翠的真假?只需要简单8步 天天短讯
- DJI RS 3 Mini发布:2千克负载仅795克,支持快速竖拍 天天新消息
- 形容法律威严的句子(精选187句)
- 《宝可梦》满血情况下受到的伤害减半,能带来多少对战机会?
- 世界热推荐:活力中国丨在忙碌的生产线感知中国经济活力
- 全球消息!海南航空回应男子在航班上喊飞机要出事:该名旅客已移交机场公安
- 陆金贷(小额应急)网贷逾期3年多久上征信|全球百事通
- 比亚迪继续减持比亚迪股份,半年已减持超30%
- 胎压监测板块1月9日涨0.91%,通达电气领涨,主力资金净流出2377.78万元_环球快消息
- 世界速看:陆金贷(小额应急)贷款逾期八天延迟还款会影响征信吗
- 記者觀察|封關壬寅末終落幕 港深雙城記開新篇 世界微动态
- 南开区16岁小孩抚养费一般多少钱
- 世界微头条丨十来万的车,我选卡罗拉
- 新华视点|商圈火、景区旺 各地消费市场显活力|聚焦
- 每日热门:光猫和路由器怎么连接 光猫和路由器的正确连接方法
- 蔬菜生吃还是熟吃?你是哪一派?|天天观点
- 天天消息!九典制药(300705.SZ):非洛地平片获批上市
- 热水泡脚脚痒是怎么回事?-环球时快讯
- 面试时,最可怕的就是背调?-世界视点
- 环球短讯![快讯]广联航空:关于特定股东减持数量过半的进展