Blog

Blog

PHODAL

【架构拾集】组件设计原则(Stage1)

日常开发模式:

  1. 选定一个基础的组件库
  2. 当我们需要在基础的组件上添加功能时,需要封装出自己的组件
  3. 当我们找不到合适的组件,则需要自己编写组件
  4. 基础组件库不存在的组件,但是存在第三方组件库,则需要进行二次封装
  5. 自己写的组件有 bug,于是修改,引出新的 bug
  6. 写的组件太臃肿了,拆分成两个组件;两个组件功能重复,于是合并成一个组件。
  7. 反复重复 2~6 步,或者只重复第 5 步,又或者是只重复第 6 步。

是的,我们主要在处理的是:难以预料的 bug。

组件的二次封装:装饰器模式

首先,我们不可能会花时间去二次封装所有的组件——除非,我们打算封装自己的组件库。然后,对于那些我们需要修改的组件来说,直接进行二次封装,倒也没有什么可说的。剩下的,我们要讨论的便是:第三方组件

在大部分的项目里,我们进行组件库选型的时候,往往选择的是开源、免费、可商用的组件。而一些基础的组件库,往往不包含一些复杂的组件,诸如于表格、富文本编辑器等组件。又或者是,某个组件的行为不符合的预期,于是乎便需要寻找一个第三方组件。

对于这些第三方组件来说,也没有什么好说的,一律进行二次封装:

  • 按需封装输入和输出
  • 按需修改成自己的样式
  • 尽可能通用化,而不是依赖于三方组件封装

这样做的目标是,降低因为三方组件的修改带来的风险——它们看上去没有基础组件库,那么强大,有强力的组织支持,笑~。万一哪天出问题了,我们还可以自己接盘来维护。

从某种意义上来说,组件的二次封装也算是组件的组合,只是呢,它适用的场景不太一样。从名称上来说,二次封装第三方组件会比组合第三方组件要适用得多。

业务组件的拆与合

天下大势,分久必合,合久必分。

组件的拆与合,仍然是我很痛苦的一个话题。哪怕是做了很多的项目,趟了很多的坑,我都没有想到最佳实践。于是乎:

  • 我们觉得 A 组件和 B 组件是同样的功能,只是参数不一样。便写成了同一个组件,后来我们便开始吐槽设计了。
  • 我们觉得 A 组件和 B 组件是两个不同的组件,于是就变成了两个组件。可是,业务一番修改之后,它们可能只存在 head 上的差异。

能大概总结一下的也只有:

  • 如果只有两三个基础属性,如样式或者显示,那么合成一个组件的话,问题并不是那么大。
  • 如果存在大量的差异,而且表现和行为又有比较大的差异,那么拆分成两个组件可能是一个不错的选择。

除此,还要看使用的地方 ,比如详情页和列表页的某些部分,在设计的初期是同样的,但是它们可能早晚会不一样——不过也可能是一样的,哈哈哈。

过度设计设计不足,是我们经常会遇到的坑。见招拆招,大抵是我们所能做的。除此,最有意思的是,一旦我们拆成了两个组件之后, 我们就不太起合回去了,哈哈哈哈。

组合或继承

组件的组合,即在引用子组件的基础上,添加一些新的行为——可能还需要在父组件上添加输入和输出。

组件的继续,即通过继续父组件,来添加一些新的行为。

继承

对于组件来说,我们关注于两部分的内容:输入输出。因此对于使用 Angular 的组件,只需要父组件暴露出 inputsoutputs,便可以很方便地继承输入和输出。

@Component({
  selector: 'app-clean-navbar',
  inputs: [...NavBarMeta.inputs],
  outputs: [...NavBarMeta.outputs],
  templateUrl: './clean-navbar.component.html',
  styleUrls: ['./clean-navbar.component.scss']
})

除此,由于大部分的 Angular 项目,使用的是 TypeScript。因此 inputs 和 outptus 等参数,也可以通过注解来拿到相应的值。

鉴于过去维护某个 10 年遗留系统的痛苦经历,我对于继承并不是那么热衷——当我们使用过多的继承时,会遇到一个天然的坑:父类层层调试。不过,如果只有一两层的继承关系,那到底是没有多大问题的。

于是乎,一个简单的方法就是使用组合——在需要的部分,加上定制的属性。

function WelcomeDialog() {
  return (
    <Dialog
      title="Welcome"
      message="Thank you for visiting our spacecraft!" />
  );
}

看上去两者好像都没有多大区别,不过按 React 官方的文档所说:

在 Facebook ,我们在千万的组件中使用 React,我们还没有发现任何用例,值得我们建议你用继承层次结构来创建组件。

关于我

Github: @phodal     微博:@phodal     知乎:@phodal    

微信公众号(Phodal)

围观我的Github Idea墙, 也许,你会遇到心仪的项目

QQ技术交流群: 321689806
comment

Feeds

RSS / Atom

最近文章

关于作者

Phodal Huang

Engineer, Consultant, Writer, Designer

ThoughtWorks 技术专家

工程师 / 咨询师 / 作家 / 设计学徒

开源深度爱好者

出版有《前端架构:从入门到微前端》、《自己动手设计物联网》、《全栈应用开发:精益实践》

联系我: h@phodal.com

微信公众号: 最新技术分享

标签