0

代码质量第 2 层 - 可重用的代码

 2 years ago
source link: https://segmentfault.com/a/1190000041296591
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

点击一键订阅《云荐大咖》专栏,获取官方推荐精品内容,学技术不迷路!

可重用的代码可以减少重复劳动。一个软件中,会有很多类似的业务场景。将这些场景抽象成可重用的代码。开发新功能时,重用代码可减少重复劳动。

可重用的代码可以减少因需求变动,导致多次改动和漏改的情况。试想,要修改全站提交按钮的颜色,如果全站有100个包含提交按钮的页面,每个页面的按钮的样式都没复用,这改动量和漏改的风险都很大。如果做成可重用的,则只需改动一处。

如何写出可重用的代码?

代码块的职责越多,越难被复用。写出可重用的代码就是:识别,分离出可复用的部分。

考虑这样的场景:代码块A 的功能是获取接口数据,并渲染 UI。代码块B 的 UI 和 A 一样,但获取的接口数据不一样。代码块C 获取的数据和 A 一样,但 UI 和 A 不一样。A,B,C 之间的代码都不能被复用。

要改成可复用的代码,就是将可复用的 UI,获取接口数据的代码独立出来。

下面,我们来看些常见的可复用的部分和复用方法。

一、UI 展示

UI 展示为外观的展示,包含:HTML 和 CSS。不包含数据的获取和事件处理。

用组件可以实现 UI 展示代码的复用。这样的组件被称为展示组件。数据和事件处理通过属性传入。Ant Design 之类的组件库里的组件均为展示组件。如下是 React 实现的新闻列表:

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 这么处理:

// 请求拦截器
axios.interceptors.request.use(...)
// 响应拦截器
axios.interceptors.response.use(...)

四、具体接口的调用

接口调用代码一般会放在一个文件中,如 service.js:

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 来封装管理后台的列表页的实现:

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 展示,接口调用,业务流程,数据,工具函数 中找出可复用的部分。

代码质量的下一层次就是:可重构的代码。我会在下一篇文章中介绍。

金伟强往期精彩文章推荐:

聊聊代码质量 - 《学得会,抄得走的提升前端代码质量方法》前言
代码质量第五层 - 只是实现了功能
代码质量第四层 - 健壮的代码
代码质量第三层 - 可读的代码

image.png
《云荐大咖》是腾讯云加社区精品内容专栏。云荐官特邀行业佼者,聚焦于前沿技术的落地及理论实践之上,持续为您解读云时代热点技术、探索行业发展新机。点击一键订阅,我们将为你定期推送精品内容。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK