可重用的代码指:在相似业务场景下,用的是同一份代码。
可重用的代码可以减少重复劳动。一个软件中,会有很多类似的业务场景。将这些场景抽象成可重用的代码。开发新功能时,重用代码可减少重复劳动。
可重用的代码可以减少因需求变动,导致多次改动和漏改的情况。试想,要修改全站提交按钮的颜色,如果全站有100个包含提交按钮的页面,每个页面的按钮的样式都没复用,这改动量和漏改的风险都很大。如果做成可重用的,则只需改动一处。
一、如何写出可重用的代码
代码块的职责越多,越难被复用。写出可重用的代码就是:识别,分离出可复用的部分。
考虑这样的场景:代码块A的功能是获取接口数据,并渲染UI。代码块B的UI和A一样,但获取的接口数据不一样。代码块C获取的数据和A一样,但UI和A不一样。A,B,C之间的代码都不能被复用。
要改成可复用的代码,就是将可复用的UI,获取接口数据的代码独立出来。
下面,我们来看些常见的可复用的部分和复用方法。
(一)UI展示
UI展示为外观的展示,包含:HTML和CSS。不包含数据的获取和事件处理。
用组件可以实现UI展示代码的复用。这样的组件被称为展示组件。数据和事件处理通过属性传入。Ant Design之类的组件库里的组件均为展示组件。如下是React实现的新闻列表:
代码语言:javascript复制import React from 'react'
import s from './style.scss'
import Item, {IItem} from './item'
export interface INewsListProps {
list: IItem[],
onItemClick: (id: number) => void
}
const NewsList: FC<INewsListProps> = ({ list, onItemClick }) => {
return (
<div className={s.list}>
{
list.map(item => (
<Item
key={item.id}
onClick={onItemClick}
payload={item}
/>
))
}
</div>
)
}
export default React.memo(NewsList)
(二)接口调用
接口调用有两部分可以复用:
- 接口请求和响应的通用处理。
- 具体接口的调用。
- 接口请求和响应的通用处理
接口调用时,常常要做一些通用的处理。比如:
- 前后端分离的网站,要在接口的请求头中要加token来标识用户。
- 接口报错时,要将错误码转化成对用户友好的错误信息。
用axios这么处理:
代码语言:javascript复制// 请求拦截器
axios.interceptors.request.use(...)
// 响应拦截器
axios.interceptors.response.use(...)
- 具体接口的调用
接口调用代码一般会放在一个文件中,如service.js:
代码语言:javascript复制export const fetchList = ...
export const fetchDetail = ...
export const createItem = ...
export const updateItem = ...
export const deleteItem = ...
接口调用,还有Loading状态管理,防抖,节流,错误重试,缓存等场景。React可以用useRequest,Vue也有类似的轮子。
(二)业务流程
很多业务流程是类似的,可以被复用。比如,管理后台列表页的业务流程都类似是这样的:
- 进入页面时,获取列表数据。
- 点搜索按钮,根据当前的查询条件,获取列表数据。
点分页,获取指定页的列表。
自定义hooks(Vue3中叫组合式API) 支持内部的状态管理和生命周期。因此,可以用hooks来封装业务流程。下面是用Vue3的组合式API来封装管理后台的列表页的实现:
代码语言:javascript复制import { onMounted, reactive, ref, Ref } from 'vue'
export interface Params {
url: string
searchConditions: Record<string, any>
}
interface Return<T> {
searchConditions: Record<string, any>
resetConditions: () => void
pagination: Record<string, any>
fetchList: (isReset: boolean) => void
list: Ref<T[]>
isLoading: Ref<boolean>
}
function useList<T extends Record<string, any>> ({
url,
searchConditions: initCondition
}: Params): Return<T> {
const searchConditions = reactive({...initCondition})
const pagination = reactive({
pageSize: 10
})
const list = ref<T[]>([]) as Ref<T[]>
const isLoading = ref(false) as Ref<boolean>
// isReset 为 true 表示搜第一页。
const fetchList = (isReset: boolean = false): void => ...
// 进入页面
onMounted(() => {
fetchList()
})
return {
searchConditions,
pagination,
fetchList,
list,
isLoading,
}
}
export default useList
推荐个hooks工具库:ahooks。Vue版:ahooks-vue。
(三)数据
有些数据指会被多个地方用到。如:登录的用户信息,权限数据。
可以用状态管理库来管理这些数据。React状态管理一般用Redux、Mobx或Context API。Vue一般用Vuex。
(四)工具函数
工具函数是与业务无关的。如:格式化日期,生成唯一的id等。Lodash和 moment.js包含了很多的工具方法。
二、总结
要写出可重用的代码,本质就是识别和分离出可复用的部分。前端可以从UI展示,接口调用,业务流程,数据,工具函数中找出可复用的部分。
代码质量的下一层次就是:可重构的代码。我会在下一篇文章中介绍。
FunTester原创专题推荐~
- 900原创合集
- 2021年原创合集
- 2022年原创合集
- 接口功能测试专题
- 性能测试专题
- Groovy专题
- Java、Groovy、Go、Python
- 单测&白盒
- FunTester社群风采
- 测试理论鸡汤
- FunTester视频专题
- 案例分享:方案、BUG、爬虫
- UI自动化专题
- 测试工具专题
-- By FunTester