共计 5179 个字符,预计需要花费 13 分钟才能阅读完成。
许久没有写博客,偶尔打开之前的博客记录,看之前的内容感叹本人之前太菜的同时,思绪万千。
迷迷糊糊写代码曾经这么久了,见过的公司,或下班,或单干,或借鉴,浏览过得代码也能够算是有一些了,有的代码不堪入目,有的就像他人评估雷军那样,代码如诗个别。
不晓得你们有没有遇到过接手他人二手我的项目时候,宛如吃了苍蝇一样的感觉,明天次要围绕
-
如何做到代码清晰简洁
-
为什么要代码清晰简洁
-
代码清晰简洁的长处是什么
-
代码的可维护性与效率
这几点简略分享一下我对代码整洁和代码思维的一些意识,如有不足之处,请各位大佬批评指正。
一、开发者之基石 ——— 面向对象三大个性七大准则
面向对象堪称是陈词滥调了,哪怕是轻易来一个面试者都能随口通知你
三大个性 封装、继承、多态
七大准则 繁多、开闭、里氏替换、接口隔离、依赖导致、迪米特和聚合复用
1. 繁多职责准则(Single Responsibility Principle)
每一个类应该专一于做一件事件。
2. 里氏替换准则(Liskov Substitution Principle)
超类存在的中央,子类是能够替换的。
3. 依赖倒置准则(Dependence Inversion Principle)
实现尽量依赖形象,不依赖具体实现。
4. 接口隔离准则(Interface Segregation Principle)
该当为客户端提供尽可能小的独自的接口,而不是提供大的总的接口。
5. 迪米特法令(Law Of Demeter)
又叫起码常识准则,一个软件实体该当尽可能少的与其余实体产生相互作用。
6. 开闭准则(Open Close Principle)
面向扩大凋谢,面向批改敞开。
7. 组合 / 聚合复用准则(Composite/Aggregate Reuse Principle CARP)
尽量应用合成 / 聚合达到复用,尽量少用继承。准则:一个类中有另一个类的对象。
整体看来,用最简略的一个词语概括就是解耦,在日常的开发工作之中做不到解耦的代码,在保护起来肯定是很苦楚的,举例说明如下。
// 公共申请办法(办法 1)methodQuery(methodModel) {
// 全局赋值
this.methodModel = methodModel
// 取值
let {
loadingName,
methodName,
methodVal,
pMehtod,
callBack
} = methodModel
// 判断是执行函数还是 promise
let baseMethod = pMehtod ? pMehtod : this[methodName](methodVal)
// loading
loadingName && (this[loadingName] = true)
// 申请
baseMethod && baseMethod.then(res => {this.callBackThen(res)
})
.catch(() => {loadingName && (this[loadingName] = false)
})
},
//promise 回调(办法 2)callBackThen(res) {
// 取值
let {
callBack,
notReset
} = this.methodModel
// 回调函数
callBack && this[callBack](res)
// 敞开动作
this.closeClass()
// 刷新表格
!notReset && this.resetPostTableBody()},
// 敞开动作(办法 3)closeClass(openMessage, mark) {
// 取值
let {
loadingName,
message,
closeMarkName
} = this.methodModel
// 敞开的数组
let markArr = mark ? mark : [closeMarkName, loadingName]
// 敞开标记
markArr.forEach(element => {element && (this[element] = false)
});
// 提醒音讯
let endMessage = openMessage ? openMessage : message
endMessage && this.$commonUtil.setMessage('success', endMessage, true)
},
这个是我最开始接触前端的时候封装的一个办法,甚至过后感觉完美无瑕,一套流程下来,程序跑的顺顺当当,直到起初业务扩大,发现函数一环套一环,多余进去的逻辑无奈满足,但因为我的项目体积过大,工夫紧,只好一点点的往里边填充各种判断,和横向裁减批改,这无疑是很显著的违反了繁多和开闭准则。
感激公司信赖,直到起初我的项目做 H5 被改良了一下如下
methodQuery(model) {
// loading 名称,音讯提醒,promise 或办法名称,办法参数,回调
let {loadingName, message, pMethod, params, callBack} = model
// 关上 loading
loadingName && (this[loadingName] = true)
// 判断传进来的是 promise 还是 办法名称
let method = typeof pMethod == 'string' ? this[pMethod](params) : pMethod
// 操作 promise
method.then(async res => {message && Toast.success(message || '操作胜利')
// 回调办法
callBack && await this[callBack](res)
}).finally(_ => {
// 敞开 loading
loadingName && (this[loadingName] = false)
})
},
又到最初从外边改成了建造者模式
我感觉这些个性和准则里边最重要的,首先正当的多态,正当的多态能够让你的代码更加灵便,下边的准则都是围绕上边的个性来讲的,假如你写了一个不参加业务的形象办法,一个办法有多种实现和你多种办法复制多份比拟起来,哪个不便保护和浏览显而易见吧。
其次最简略的要晓得一个繁多准则,一个开闭准则,一个函数只做一件事,不要让本人和他人回过头来看本人代码的时候每次都要找了五分钟能力找到重点,节约了他人的工夫。
说到这里我比方吐槽一下最近二开的一个 php 的我的项目
权且不说这大段的各种姿态的循环,我万万没有想到一个函数竟然有 700 行之巨!!!真是不吐不快!
回忆起这番经验的时候,我只是感觉进去混早晚是要还的,或者前期保护的时候本人一边改本人的代码一边骂本人 2B,或者他人改本人代码的时候骂本人是 2B,而且写出不便保护的代码不会出奇奇怪怪的 bug,也能更少的加班何乐而不为呢。
二、开发者之矛 ———— 设计模式的思维与清晰的目录构造划分
设计模式,记得有一次面试的时候,问到那个面试者,你罕用的设计模式有哪些,而后他答复我依照网上的例子写了几次,感觉很不不便,起初就不怎么用了。
在这里我想表白的是,写代码切记不要生吞活剥,重要的是思维。
也会有人说前端不须要设计模式,这显然是不正确的,设计模式在 oo 社区里被宽泛的利用与推广,设计模式作为设计思维,与语言无关。
简略介绍下我比拟喜爱的几种设计模式,建造者、抽奖工厂、策略模式
策略模式的定义是:定义一系列的算法,把它们一个个封装起来,并且使它们能够互相替换。
我对策略模式的意识说来惭愧还是因为大段的 if else 判断的状况下被老同志批评之后才意识的,过后真的是有一种恍然大悟的感觉。简略举个栗子。
go(val) {if (val === 'a') {return !!val}
if (val === 'b') {console.error('123')
}
if (val === 'c') {return val || 'reset'}
}
如上代码一个函数里边判断了四种状况,针对不同的状况去执行不同的操作,在这种状况下。
- 首先假如用户加了十种状况,那么这段代码的浏览即将会无比的差,在扩大的时候不足弹性。
- 其次算法的复用性差,比方其余中央有相似其中的某一种算法的时候,这部分代码不能服用,那么怎么办呢,我置信必定会有人呈现复制的想法,那么就又陷入了代码保护工作量微小的问题。
更改后代码如下
let demoConfig = {
a: 'a',
b: 'b',
c: 'c'
}
a(val) {return !!val}
b() {console.error('123')
}
c(val) {return val || 'reset'}
go(val) {let methodName = Reflect.get(demoConfig, val)
methodName(val)
}
那么更新之后的这段代码有什么长处呢
- 参加了更少的业务逻辑,加强各个算法的可移植性,比方可能多个中央都用到了算法 a 等
- 有了独自的配置项之后,能够清晰的晓得,当参数是某种策略后会去做什么事件,而不是在大篇幅的代码中寻找本人想要的策略
同样为什么说设计模式是一种思维,这个思维能够用到任何实用的中央,比方表单校验,比方环境变量再比方写 html 厌倦了,换个口味 jsx 中的模板渲染。
还有不得不说的之前遇到的大段的 if else 升级版 switch
const expr = 'Papayas';
switch (expr) {
case 'Oranges':
console.log('Oranges are $0.59 a pound.');
break;
case 'Mangoes':
case 'long':
console.log('Mangoes and papayas are $2.79 a pound.');
// expected output: "Mangoes and papayas are $2.79 a pound."
break;
case 'Papayas':
console.log('Mangoes and papayas are $2.79 a pound.');
// expected output: "Mangoes and papayas are $2.79 a pound."
break;
case 'Oranges':
console.log('Oranges are $0.59 a pound.');
break;
default:
console.log(`Sorry, we are out of ${expr}.`);
}
之前形象工厂和建造者写过博客就不赘述了
形象工厂点击传送门
建造者模式 点击传送门
这两种设计模式属于创立型模式,集体认为这种创立型模式,很实用于那种反复性能且中规中矩定制的外包我的项目,后期花一些工夫,把各个代码工厂整机写好之后,通篇配置项就能够实现一个残缺的产品,举个例子,A 的商城中须要订单、购物车、商品列表,B 的企业官网须要商品列表、文章列表,C 的博客站须要文章列表、书籍商品列表、购物车
那么咱们齐全没有必要去做反复的工作把每一份代码都从新定制一遍。
或者你会说这三个我的项目每个我的项目都有本人独立的逻辑,生吞活剥必定不应用,这又要讲到另一个思维,叫做依赖注入,管制反转。
为什么前边说要尽可能吧把业务和根底拆离开,就前端而言,写 ui 的时候颗粒度肯定要尽可能的细化,你的组件和页面模板不参加业务,咱们只须要写出应用的业务注入到页面模板当中去达到咱们要的业务就能够了。
再比如说当初 git 上边那么多的开源的各种 ui 组件库,各种的开源的网站生成器,代码生成器等等等等,我想他们在做我的项目的时候必定不会说每一个我的项目都要从新写一遍的那种。
所以总结来说,写代码最要害的是一个思维的问题。
一个清晰的目录构造,写起代码起来事倍功半,拿 vue 举例
- 组件
- 页面
- 工具类
- 混入
- 申请层
- 中间件层
- 业务层
- 枚举
- 动态资源
- 初始化 扫描等配置
还有里边的细化,业务组件,根底组件,业务办法,根底办法,是否专用之类的
之前写的一个仿 vue-cli 的脚手架 zjs-template-cli 有 node 环境的话间接
npm i zjs-template-cli -g
zjs-cli init demo
就能够生成一个 vue 的脚手架,也是之前刚接触前端的时候做的,大佬们多多批评,最近会更新一版 ts 的到这个上边,喜爱的能够试试哦~~~ (^▽^)
开发者之盾 ———— 防御性编程的意识
防御性编程 (Defensive programming)是一种具体体现,它是为了保障,对程序的不可预感的应用,不会造成程序性能上的损坏。它能够被看作是为了缩小或打消墨菲定律效劳的想法。进攻式编程次要用于可能被滥用,恶作剧或无心地造成灾难性影响的程序上。
上边这句话摘自百度百科
首先来聊一下什么叫做防御性编程,集体愚见防御性编程的这种意识,是对咱们开发者的一个爱护,在开发我的项目中防止咱们遇到许多莫名其妙的不在预期之中的问题,是缩小 bug 和进步工作效率的一个意识。
我之前是做了有快两年的财务我的项目,简略分享一个之前的我的项目过程
不小心点了公布 如有有余大佬们请批评指正 今天持续补上 喜爱的点个赞吧..