js设计模式(八)-总体感受一下设计模式

news2024/12/23 13:56:34

前言

首先,不得不说我们是站在巨人的肩膀上写代码,前辈们已经很合理的帮助我们总结出来了23种设计模式,虽然有些已经被语言直接使用Api实现了,感谢走在前沿的攻城狮。

但是真真正正的看一遍所有的设计模式还是很有必要的,一开始认为 设计模式 不是雪中送来的炭,而是锦上添加的花,为什么这么说呢?因为99.99999%的需求,不考虑设计模式,只使用最基本的分支+循环语句就可以实现,而设计模式只是将这些逻辑有效的整合了起来,提高了可读性、可维护性。确实是这样的,传说中的【屎山粪海】也是这么来的。

我对设计模式的理解还只是一个不求甚解的阶段,就是只是知道有哪些设计模式以及部分模式有过使用经验的阶段,下面从切身实际的一个小场景的实现来探讨一下设计模式对开发人员会带来哪些影响:

前端的话就用轮播来记录一下吧!

设计模式之前

时间就回到4年前的时候了,大概是这样子写的:

<div><ul><li onclick="handleClickItem(0)"></li><li onclick="handleClickItem(1)"></li><li onclick="handleClickItem(2)"></li><li onclick="handleClickItem(3)"></li></ul><div class="left-btn" onclick="handleClickLeft"></div><div class="right-btn" onclick="handleClickRight"></div><div class="tools"><ul><li onclick="handleClickTool(0)"></li><li onclick="handleClickTool(1)"></li><li onclick="handleClickTool(2)"></li><li onclick="handleClickTool(3)"></li></ul></div>
</div>
<script> function handleClickItem(i) {}function handleClickLeft() {}function handleClickRight() {}function handleClickTool(i) {} </script> 

如上代码,我相信每个前端可能都写过,至少看过吧!

大概的效果就是,上面四个li在轮流显示,一个左右按钮,然后下面的li来展示当前展示的div的位置。

功能肯定是没问题的,但是这是纯为了实现功能去实现的代码,简单说几点他的问题:

1.增加轮播项怎么办?
2.顺序发生变化了怎么办?
3.在一个页面上有多个这样子的轮播?

实际模式之中

为了满足上面提出的三个问题,我们开始考虑如何解决这个问题,就出现了如下的实现方式:

<div id="loogWrap"></div>

<script> function initLoop(id, data) {const wrap = document.getElementById(id)const leftBtn = '<div class="left-btn" id="leftBtn"></div>'const rightBtn = '<div class="left-btn" id="rightBtn"></div>'const tools = `<ul id="toolsBar">${data.map((item) => `<li data-id="${item.id}"></li>`)}</ul>`const items = `<ul id="itemWrap">${data.map((item) => `<li data-id="${item.id}"><img src="${item.src}"/></li>`)}</ul>`wrap.appendChild(leftBtn)wrap.appendChild(rightBtn)wrap.appendChild(tools)wrap.appendChild(items)const lbtn = document.getElementById('leftBtn')const rbtn = document.getElementById('rightBtn')const toolbar = document.getElementById('toolsBar')const itemWrap = document.getElementById('itemWrap')lbtn.addEventListener('click', function (e) {})rbtn.addEventListener('click', function (e) {})rbtn.addEventListener('tools', function (e) {})rbtn.addEventListener('items', function (e) {})
}

const data = Array(5).fill({id:1, src:'img'})

initLoop(id, data) </script> 

呐,这已经有意识的开始令这个轮播变得有点意思了,而且不再关注页面的布局了,只需要修data就可以实现数据的变化,而且想复用的话,只需要写个 div 然后 执行一下 initLoop 方法就可以构建出来一个新的轮播。

同样的实现方式如我前面写的一篇文章中的:工具 - 我又手写轮播了,也是这样做的。文章里面还结合了 jquery 的一些 Api。

如果这时开始了解设计模式的话,已经可以很快的使用 创建型 模式中的方法来创建一个轮播了,比这个更优雅:

 class loogEvent {constructor(selector, data) {this.$dom = document.querySelector(selector)this.data = datathis.current = 0this.init()}init() {this.$dom.appendChild(this.takeBtn('left'))this.$dom.appendChild(this.takeBtn('right'))this.$dom.appendChild(this.takeTools())this.$dom.appendChild(this.takeItems())this.addEvent()}takeBtn() {}takeTools() {}takeItems() {}addEvent() {leftBtn.addEventListener('click', this.change)rightBtn.addEventListener('click', this.change)tools.addEventListener('click', this.change)items.addEventListener('click', this.currentItem)}change(i) {switch (i) {case 'left':this.current -= 1breakcase 'right':this.current += 1breakcase typeof i === 'number':this.current = ibreakdefault:break}}currentItem() {}}const loop = new loogEvent('#wrap', []) 

这一段代码就已经开始使用 创建型 模式去构建 轮播这个功能了,当然上面这段代码可能跑不通哈,只是展示一下思路,有兴趣的小伙伴可以实现它。总体思路就是所有的逻辑都尽可能的放在了 js 里面,可以实现微操。

但是这也还有一些问题:

1.我有多个动画效果,组件A使用的是渐入渐出,组件B则希望是平滑移入移出…
2.有些要显示左右按钮,有些则不显示…
3.工具条的样式也不尽相同,有点的,有条的…

设计模式之后

到之中这一步的时候,其实已经可以看到,现在追求的已经不是说如何去实现这个轮播了,而是如何能够更优雅的实现轮播。上面的思路都是,把轮播作为一个整体,由一个统一的入口一口气实现它,每次想设计一个新的轮播则需要重新申明一个轮播类。然后去实例化。

而且可以回想一下如果在 vue 里面使用双向绑定是怎么实现一个轮播的?

1.在template中使用 v-for 的方式写好页面结构
2.使用 @click 的方式去触发Vue实例里面的方法
3.配合 过渡实现轮播

还是我的另一篇文章我也做了:Vue组件-景深卡片轮播

可以看到,我们其实并没有向前面那两种思路那样,去手动的写入dom,然后微操数据等等,vue 已经帮忙给做了,而且有些方法例如 init 方法,也是 vue 帮忙实现的。

抛开 vue 是怎么实现的,再回过头来考虑上面的几个问题:

1.多个动画 => 一个动画库或多个动画类(start,end)
2.不一样的按钮 => 一个按钮库或多个按钮类
3.工具条不一样 => 定制化的工具条

我们就可以做出如此的设计:

1.提供一个方法库,用来实现获取dom属性、窗口属性、鼠标属性的固定方法(命令模式)
2.提供多个动画类,返回 start/end 两个属性,供主逻辑获取开始和结束的样式(访问模式)
3.提供多个工具条类,主流程上使用 use 方法挂载在主逻辑里面(桥接模式)
4.左右按钮进行抽离,只和主逻辑上的 current 进行交互(中介者模式)
5.还可以加一个备忘录,存在 localstorage 里面,下次直接用

7…

这就是在造火箭了。也是为什么面试的时候会面试那些造火箭的问题的原因,上面的方法大家都会,总得问点不一样的东西吧,不然凭什么选你?

而且这些也只是理论上的逻辑,具体操作还是要看公司需求和工期,不过90%的人都做到之中那种效果就不再往下去细究了,一没时间二没精力还没啥用,不以开源造福人类为目的,写的太复杂还真的没啥用。

后话

趁着这个机会又看了一遍这些设计模式,其实前前后后已经看了好几遍了,但是真的是看过就忘了,所以这次一边看,一遍记,有些理解和认识的模式,会自己写几行代码体验一下,有些压根没用过或者看不懂的依旧是看不进去。

然后就是对设计模式的一些理解了,设计模式被好多人称之为【套路】。确实是这样的,并不是说每个人都需要熟练的去使用这些套路,但是你在遇到别人用的时候,至少知道他在干嘛,例如:玩盲僧不知道 R闪 是不是太外行了,哪怕自己手残按不出来,但是肯定是要知道的呀!

套路能得人心,但是还是要待人以诚。

see U!

最后

最近找到一个VUE的文档,它将VUE的各个知识点进行了总结,整理成了《Vue 开发必须知道的36个技巧》。内容比较详实,对各个知识点的讲解也十分到位。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/147433.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MyBatis查询数据库

1.MyBatis 是什么&#xff1f; MyBatis 是⼀款优秀的持久层框架&#xff0c;它⽀持⾃定义 SQL、存储过程以及⾼级映射。MyBatis 去除了⼏乎所有的 JDBC 代码以及设置参数和获取结果集的⼯作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接⼝和 Java POJO&#xf…

计算机基础——计算机分类

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 前言 本章将会讲解计算机分类应用领域以及发展趋势 一.计算机分类 计算机并非只有日常所…

并行计算 Clion配置使用OpenMP

文章目录配置CMakeList.txt文件OpenMP之HelloWorld数据共享属性shared子句private子句default子句default(shared)default(none)配置CMakeList.txt文件 文件底部加入以下内容&#xff0c;即可支持OpenMP FIND_PACKAGE(OpenMP REQUIRED) if (OPENMP_FOUND)message("OPENM…

STM32MP157驱动开发——Linux DAC驱动

STM32MP157驱动开发——Linux DAC驱动0.前言一、DAC 简介二、驱动源码分析1.设备树下的 DAC 节点2.驱动源码分析1&#xff09;stm32_dac 结构体2&#xff09;stm32_adc_probe 函数3&#xff09;stm32_dac_iio_info 结构体三、驱动开发1.修改设备树2.使能DAC驱动四、 运行测试0.…

读书笔记 -公司改造 和 紧迫感

读书笔记 -公司改造 - 三枝匡 读书笔记 -公司改造 - 三枝匡 2022 年夏天的时候在微信读书上读了这本书&#xff0c;这是我们 CSDN 的创始人蒋涛推荐的&#xff0c;当时记了一些笔记如下。 总结&#xff1a; 每个有一定的历史&#xff0c;比较成功、或者尚未非常成功的公司遇…

基于Java+SpringBoot+vue+element实现毕业就业招聘系统

基于JavaSpringBootvueelement实现毕业就业招聘系统 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java毕设项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末获取源码…

用最简单的案例带你掌握C++中各种指针

1、前言 指针&#xff0c;作为C/C中最神秘、功能最强大的语法&#xff0c;着实是难以理解 、难以掌握、难以运用。&#x1f625; 但是&#xff0c;能灵活的使用指针&#xff0c;对利用C/C开发程序将有很大的帮助&#xff0c;让我们一起来了解了解吧。 2、啥是指针&#xff1f…

参加《2022 中国开发者影响力盛典》我的 4 重收获!

感谢 CSDN 邀请&#xff0c;西红柿有幸参加了 2022 中国开发者影响力盛典暨 CSDN 企业生态汇&#xff0c;让我有了一个不虚此行的下午&#xff0c;也跟大家分享一下我在会上的 4 重收获吧~第一重收获&#xff1a;互联网圈大佬 会议聚焦开发者生态建设主题&#xff0c;分享了 CS…

分布式基础篇4 —— 基础篇完结

分类维护一、三级分类后端实现准备工作跨域问题关闭 ESLint 检查前端实现二、分类删除前端完善分类列表后端实现——删除配置发送请求代码片段前端实现——删除三、分类增加前端实现四、分类修改五、拖拽菜单拖拽效果实现拖拽数据收集拖拽功能完成拖拽功能完善六、批量删除品牌…

JS知识补充-JS原型链

概述JS原型链别名&#xff1a;隐式原型链作用&#xff1a;根据一定路径查找属性&#xff08;方法&#xff09;作用举例&#xff1a;我们定义一个构造函数Fn&#xff0c;使用此构造函数创建一个对象fn1&#xff0c;接着使用创建的对象fn1去调用toString方法并打印&#xff0c;我…

【阶段三】Python机器学习03篇:机器学习中的函数、机器学习中的梯度下降、机器学习的数据结构:张量与机器学习概率与统计基础

本篇的思维导图: 机器学习中的函数 函数描述了输入与输出的关系。在函数中,一个事物(输出)随着另一个(或一组)事物(输入)的变化而变化,如下图所示。 输入与输出的关系一般情况下,用x(或x1,x2,x3,…)表示输入,用y表示输出,并把它们叫作变量,…

Java设计模式中的设计原则/开闭原则、里氏代换原则和依赖倒转原则又是什么,怎么用

继续整理记录这段时间来的收获&#xff0c;详细代码可在我的Gitee仓库SpringBoot克隆下载学习使用&#xff01; 3.设计原则 3.1 目的 提高软件系统可维护性与可复用性增加软件可扩展性与灵活性节约开发成本与维护成本 3.2 开闭原则 3.2.1 特点 对扩展开放&#xff0c;对修…

实战干货|自研数据存储迁移MySQL实战

背景 最近公司内部在做某自研数据存储的下线工作&#xff0c;这里我们暂且化名其为DistributeSQL&#xff0c;由于DistributeSQL不再进行服务支持&#xff0c;需要迁移项目中使用到该存储到其他数据存储中。 本篇来聊聊这次在数据存储迁移过程中的方案设计思路、实现的大致细节…

中老年服装电商小程序开发

近年来&#xff0c;随着网络的发展&#xff0c;中老年服装电商小程序开发有了很大的进步。这种平台不仅可以方便用户购买到最新最时尚的产品&#xff0c;而且还能帮助商家提高销售业绩。 1&#xff1a;中老年服装电商小程序开发的优势 中老年人对商品信息需求大、容易接受新鲜…

实验⼀:Windows主机漏洞利⽤攻击实践

永恒之蓝简介 永恒之蓝&#xff08;Eternal Blue&#xff09;爆发于2017年4月14日晚&#xff0c;是一种利用Windows系统的SMB协议漏洞来获取系统的最高权限&#xff0c;以此来控制被入侵的计算机。甚至于2017年5月12日&#xff0c; 不法分子通过改造“永恒之蓝”制作了wannacry…

【ROS】—— ROS重名问题(九)

文章目录前言1. ROS工作空间覆盖2. ROS节点名称重名2.1 rosrun设置命名空间与重映射2.1.1 rosrun设置命名空间2.1.2 rosrun名称重映射2.1.3 rosrun命名空间与名称重映射叠加2.2 launch文件设置命名空间与重映射2.3 编码设置命名空间与重映射2.3.1 重映射2.3.2 C 实现:命名空间3…

Maven基础学习——依赖配置(1):配置同一项目下的三个工程

依赖配置一、前言二、创建第一个工程三、新建第二个工程四、创建第三个工程五、配置1.每个工程的.xml文件2.文件配置六、结语一、前言 在讲述依赖配置时&#xff0c;需要使用实例来说明&#xff0c;在B站黑马课程&#xff08;第12小节&#xff09;中没有讲到如何配置基础的三个…

[Effective Objective] 熟悉Objective-C

了解 Objective-C Objective_C 是一种面向对象的语言。但与jave、C等语言不同&#xff0c;它使用了消息结构&#xff08;messaging structure&#xff09;而非函数调用&#xff08;function calling&#xff09;。Objective-C由Smalltalk演化而来&#xff0c;后者是消息语言的…

React 学习笔记总结(六)

文章目录1. redux 介绍2. redux 工作流程3. redux 的使用4. redux 完整结构补充5. redux的 异步action6. react-redux库 与 redux库7. react-redux库的 实战8. react-redux的connect 最精简写法9. react-redux的 Provider组件作用10. react-redux 整合UI组件 和 容器组件11. re…

webgl图形平移、缩放、旋转

文章目录前言平移图示代码示例缩放图示代码示例旋转公式推导代码示例总结前言 在webgl中将图形进行平移、旋转、缩放的操作称为变换或仿射变换&#xff0c;图形的仿射变换涉及到顶点位置的修改&#xff0c;通过顶点着色器是比较直接的方式。本文通过着色器实现对webgl图形的仿…