设计模式在vue中的应用(一)

18,929 阅读6分钟

前言

目录整理:
设计模式在vue中的应用(一)
设计模式在vue中的应用(二)
设计模式在vue中的应用(三)
设计模式在vue中的应用(四)
设计模式在vue中的应用(五)
设计模式在vue中的应用(六)
设计模式在vue中的应用(七)

为什么要写这些文章呢。正如设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结(来自百度百科)一样,也是想通过分享一些工作中的积累与大家探讨设计模式的魅力所在。
在这个系列文章中为了辅助说明引入的应用场景都是工作中真实的应用场景,当然无法覆盖全面,但以此类推也覆盖到了常见的业务场景



最近需要维护一个老项目,里面有个需求如下:
有一个页面要根据路由参数type分别渲染三个表单,三个表单中有相同的输入项也有不同的输入项其中某些输入项又会有一个对应的xstatus来判断需不需显示。

一,需求

需求很简单就如文章开篇,公司项目暂时不方便贴出来,只好强行意淫一个场景帮助理解。

假设:我现在要将登陆、手机注册、邮箱注册通过一个路由用参数type标识渲染那个表单;登陆过程中如果账号密码输入错误次数超过3次就需要输入图像验证码,通过codeStatus进行标识。

二,代码

当我们接手维护一个老项目时遇到各种问题总是会抱怨别人家的代码,好,我们先来看一下别人家的代码

这种代码实现想必大家都身经百战了,就不贴详细实现了。逻辑很简单,按需求每个form根据type做if判断,然后input根据status做if操作。

我接手的老项目需求要比这个复杂的多,内部实现就是这么搞的,仅template就近500多行。我要处理的需求很简单——修改其中一个input对应的字段名,看着这个文件我是万脸懵逼,关键是提测后没有通过,由于对这个文件处理的业务逻辑不熟,需要修改的这个input在两个表单里面分别由两个不同的status来判断显示状态,而我只改了一个地方的

吐槽谁都会,吐槽完了就得优化这块逻辑了

三,优化一

无脑操作:

既然有三个表单我们就封装三个form组件,每个组件负责自己的渲染逻辑

为什么说是无脑操作呢,写过vue的coder这种方式已经深入我们的血脉了,哈哈哈哈哈。
看下效果怎么样——

假设项目原本采用这种方式组织代码,我要去完成改input字段名的需求,我还是可能只改了register-mobile遗漏掉register-email,最终结果提测不通过,有bug了

老实说这种方式只是将500+行代码分成了三个文件而已,至于优化还谈不上,说代码美化还差不多

四,优化二

设计模式登场,先看代码
目录结构:

文件Login.vue
文件RegisterMobile.vue
文件./input/ImgCode.vue
怎么做的呢,我们在优化一的基础上将每个input也组件化了,每个input组件接受typestatus两个属性,form以组件的形式使用input,这样我们对input的修改会自动更新到所有引用了的form,input是否显示的逻辑在input组件内部有自己控制
看下效果怎么样——

假设项目采用这种代码组织方式,我要去完成改input字段名的需求。找到对应的input组件,完全不用关心对typestatus的判断逻辑,只需修改字段名。因为两个form使用了同一个input,自测register-mobile没问题,那么register-email同样不会有问题,就算业务不熟悉,也不会出现前面尴尬的状况——bug。提交测试。转身就下楼喝咖啡,就是这么自信。

效果好像很赞。这节开头就提到了设计模式,那到底用到了什么设计模式呢。先来点理论知识:

外观模式:为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。引入外观角色之后,用户只需要直接与外观角色交互,用户与子系统之间的复杂关系由外观角色来实现,从而降低了系统的耦合度

LoginRegisterMobileRegisterEmail定义了三个外观角色,每个input组件作为子系统。外观角色只关心使用那些子系统,子系统对status的逻辑在子系统内部处理,这样就降低了系统的耦合度

五,优化三

取名字终究是一件比较伤脑的事,根据上面的实现我们需要三个form组件LoginRegisterMobileRegisterEmail这一下要取三个名字,头疼!!!
就不能一个组件Form.vue吗

将所有的input组件注册到form组件上,因为input组件内部有通过typestatus来判断自己需不需要显示,我们的需求同样达到了
看下效果怎么样——

将原本的三个组件简化成一个组件,在这个点上确实达到了优化的效果。但是有一个缺点,当业务逻辑很复杂顺着这个规则写下去,可能在form组件里面注册非常多的input组件,如果我们想知道那些input组件会在手机注册时用到,单从form组件是无法判别的,需要从这些input组件的内部逻辑一个一个看下去,才能得到我们想要的结果,不得不说这个过程是痛苦的。

六,优化四

优化三的问题是在某个给定的type下实例化了很多无用input,虽然它们有内部逻辑判断不会显示。如果我们要什么组件就给我们那个组件就好了。

我想要iphoneX,大佬能造一个吗?大佬:好
我想要mete20,大佬能造一个吗?大佬:好
我想要小米,大佬能造一个吗?大佬:好

大佬这么牛逼,大佬是谁呀?答:富士康——手机工厂

工厂模式

首先造一个input factory,专门用来生成input:

启用工厂生产:

七、结尾

为了完成文章开篇这个小需求,我们使用了设计模式中的外观模式、工厂模式。相比于系统原本的实现方式,优化后的方案系统解耦程度更高,可维护性更强。


本文实现同样适用于react,为什么文章以vue做题?vue的template让我们在理解一些概念的时候可能会有点不适应,而react的jsx可以看做就是在写JavaScript对各种概念实现更灵活
友情提示:设计模式在vue中的应用应该会写一个系列,喜欢的同学记得关注下