关于javascript:优秀组件设计的关键自私原则

5次阅读

共计 12206 个字符,预计需要花费 31 分钟才能阅读完成。

本文首发于微信公众号:大迁世界, 我的微信:qq449245884,我会第一工夫和你分享前端行业趋势,学习路径等等。
更多开源作品请看 GitHub https://github.com/qq449245884/xiaozhi,蕴含一线大厂面试残缺考点、材料以及我的系列文章。

当把组件从设计转化为开发时,经常会发现一些属性与内容无关,而与组件自身无关。这种考虑周到的组件设计办法导致了简单的属性、更平缓的学习曲线和最终的技术债权。然而,防止这些陷阱的要害是自私或自我利益为核心的组件设计。

在开发新性能时,是什么决定了现有组件是否可行?当一个组件不能应用时,这到底意味着什么?

该组件在性能上是否没有做它所冀望的事件,比方一个标签零碎没有切换到正确的面板?或者它太死板,不能反对设计的内容,比方一个在内容之后而不是之前有图标的按钮?或者是它太过预设和结构化,无奈反对轻微的变体,比方一个始终有题目局部的模态,当初须要一个没有题目的变体?

这就是组件的生存。很多时候,它们是为了一个狭隘的指标而构建的,而后匆忙地为一个接一个的小变动进行扩大,直到不再可行。在这个时候,会创立一个新组件,技术债权增长,入职学习曲线变得更平缓,代码库的可维护性变得更具挑战性。

这仅仅是组件不可避免的生命周期吗?还是这种状况能够防止?最重要的是,如果能够防止,怎么做?

自私。或者说,自利。更好的说法可能是两者兼而有之。

很多时候,组件过于体贴。它们对彼此太体贴了,尤其是对它们本人的内容太体贴了。为了创立可能随着产品扩大的组件,要害是自私地关注本人的利益——冷酷、自恋、世界环绕着我旋转的自私。

本文并不打算解决自利和自私之间几百年的争执。坦白说,我没有资格参加任何哲学答辩。然而,本文要做的是证实构建自私组件对其余组件、设计师、开发者和应用你内容的人来说是最无利的。事实上,自私的组件在它们四周发明了如此多的益处,以至于你简直能够说它们是自私的。

留神:本文中的所有代码示例和演示都将基于 React 和 TypeScript。然而,这些概念和模式是与框架无关的。

思考的迭代

兴许,展现一个体贴的组件的最好形式是通过走过一个组件的生命周期。咱们将可能看到它们是如何开始时很小,性能很强,但一旦设计倒退起来就会变得很轻便。每一次迭代都会使组件进一步陷入困境,直到产品的设计和需要超过了组件自身的能力。

让咱们考虑一下虚心的 Button 组件。它具备欺骗性的复杂性,而且常常被困在思考模式中,因而,是一个很好的工作实例。

迭代 1

尽管这些样本设计相当简陋,比方没有显示各种 :hover:focus:disabled状态,但它们的确展现了一个有两种色彩主题的简略按钮。

乍一看,所产生的 Button 组件有可能和设计一样是赤裸裸的。

// 首先,从 React 扩大原生 HTML 按钮属性,如 onClick 和 disabled。type ButtonProps = React.ComponentPropsWithoutRef<"button"> & {
  text: string;
  theme: 'primary' | 'secondary';
}
<Button
  onClick={someFunction}
  text="Add to cart"
  theme="primary"
/>

有可能,甚至有可能,咱们都见过这样的一个 Button 组件。兴许咱们甚至本人也做过这样的一个。有些名字可能不一样,但 props 或 Button 的 API 大抵上是一样的。

为了满足设计的要求,Button 为 themetext 定义了 props。这第一个迭代工作,满足了设计和产品的以后需要。

然而,设计和产品的以后需要很少是最终需要。当下次设计迭代时,增加到购物车的按钮当初须要一个图标。

迭代 2

在验证了产品的用户界面后,决定在增加到购物车的按钮上减少一个图标,这将是无益的。不过,设计人员解释说,不是每个按钮都会包含一个图标。

回到咱们的 Button 组件,它的 props 能够用一个可选的 icon 来扩大,该 props 映射到一个图标的名称,以便有条件地渲染。

type ButtonProps = {
  theme: 'primary' | 'secondary';
  text: string;
  icon?: 'cart' | '...all-other-potential-icon-names';
}
<Button
  theme="primary"
  onClick={someFunction}
  text="Add to cart"
  icon="cart"
/>

呜呼! 危机解除了。

有了新的 icon prop,Button 当初能够反对带或不带图标的变体。当然,这假设图标总是显示在文本的开端,但出其不意的是,在设计下一次迭代时,状况并非如此。

迭代 3

以前的 Button 组件的实现包含文本开端的图标,但新的设计要求图标能够抉择放在文本的结尾。繁多的 icon prop 将不再适宜最新设计要求的须要。

有几个不同的方向能够用来满足这个新产品的要求。兴许能够给 Button 增加一个iconPosition prop。但如果须要在两边都有一个图标呢?兴许咱们的 Button 组件能够当先于这个假如的要求,对 prop 做一些扭转。

繁多的 icon prop 将不再适宜产品的须要,所以它被移除。取而代之的是两个新 prop,iconAtStarticonAtEnd

type ButtonProps = {
  theme: 'primary' | 'secondary' | 'tertiary';
  text: string;
  iconAtStart?: 'cart' | '...all-other-potential-icon-names';
  iconAtEnd?: 'cart' | '...all-other-potential-icon-names';
}

在重构代码库中 Button 的现有用处以应用新的 props,另一个危机被防止了。当初,Button 有了一些灵活性。所有这些都是硬编码的,并被包装在组件自身的条件中,但能够必定的是,UI 不晓得的货色不会挫伤它。

到目前为止,Button 图标始终是与文本雷同的色彩。这仿佛是正当的,也是一个牢靠的默认值,但让咱们通过定义一个具备对比色的图标的变体来给这个运行良好的组件带来麻烦。

迭代 4

为了提供一种反馈感,这个确认用户界面阶段被设计为在物品被胜利增加到购物车时长期显示。

兴许这个时候,开发团队会抉择对产品需要进行出击。但尽管如此,还是决定持续推动为 Button 图标提供色彩灵活性。

同样,能够采取多种办法来解决这个问题。兴许一个iconClassName prop 被传递到 Button 中,以便对图标的外观有更好的管制。然而,还有其余的产品开发重点,因而,只能做一个疾速修复。

因而,一个 iconColor prop 被增加到 Butto n 中。

type ButtonProps = {
  theme: 'primary' | 'secondary' | 'tertiary';
  text: string;
  iconAtStart?: 'cart' | '...all-other-potential-icon-names';
  iconAtEnd?: 'cart' | '...all-other-potential-icon-names';
  iconColor?: 'green' | '...other-theme-color-names';
}

随着疾速修复的到位,Button 图标当初能够采纳与文本不同的格调。UI 能够提供所设计的确认,而产品能够再次向前推动。

当然,随着产品要求的一直增长和扩充,他们的设计也在一直倒退。

迭代 5

在最新的设计中,Button 当初必须只用一个图标来应用。这能够用几种不同的办法来实现,然而,所有这些办法都须要进行肯定水平的重构。

兴许一个新的 IconButton 组件被创立,将所有其余的按钮逻辑和款式反复到两个中央。或者,这些逻辑和款式被集中起来,在两个组件中共享。然而,在这个例子中,开发团队决定将所有的变体放在同一个 Button 组件中。

相同,text prop 被标记为可选。这能够像在 props 中标记为可选一样疾速,但如果有任何冀望文本存在的逻辑,可能须要额定的重构。

然而问题来了,如果 Button 只有一个图标,应该应用哪个图标道具?iconAtStarticonAtEnd 都没有适当地形容 Button。最终,咱们决定把原来的图标道具带回来,用于仅有图标的变体。

type ButtonProps = {
  theme: 'primary' | 'secondary' | 'tertiary';
  iconAtStart?: 'cart' | '...all-other-potential-icon-names';
  iconAtEnd?: 'cart' | '...all-other-potential-icon-names';
  iconColor?: 'green' | '...other-theme-color-names';
  icon?: 'cart' | '...all-other-potential-icon-names';
  text?: string;
}

当初,Button 的 API 越来越令人困惑。兴许在组件中留有一些正文,以解释何时和何时不应用特定的 prop,但学习曲线越来越平缓,出错的可能性也越来越大。

例如,如果不给 ButtonProps 类型减少微小的复杂性,就无奈阻止一个人同时应用 icon 和 text prop。这可能会毁坏用户界面,或者在 Button 组件自身中用更简单的条件来解决。此外,icon prop 也能够与 iconAtStartIconAtEnd prop 中的一个或两个一起应用。同样,这可能会毁坏用户界面,或者在组件内用更多的条件层来解决。

咱们可爱的 Button 在这一点上曾经变得相当难以治理了。心愿产品曾经达到一个稳固点,不会再有新的变动或要求产生。永远。

迭代 6

这么说来,永远不会有任何变动了。🤦

Button 的下一个也是最初一个迭代是传说中压垮骆驼的那根稻草。在增加到购物车的按钮中,如果以后物品曾经在购物车中,咱们想在按钮上显示其中的数量。从外表上看,这是一个间接的变动,即动静地建设 text prop 字符串。然而这个组件被突破了,因为以后商品数量须要一个不同的字体分量和下划线。因为 Button 只承受纯文本字符串,没有其余子元素,所以这个组件不再工作。

这个设计如果是第二次迭代的话,会不会导致按钮生效呢?兴许不会。那时组件和代码库都还很年老。然而到目前为止,代码库曾经增长了很多,要为这个需要进行重构几乎就像是攀登高峰。

这时可能会产生以下事件之一。

  • 做一个更大的重构,把 Button 从一个 text prop 移到承受 children 或承受一个组件或标记作为 text
  • 该 Button 被宰割成一个独自的 AddToCart 按钮,有一个更严格的 API,专门用于这一个用例。这也是将任何按钮的逻辑和款式复制到多个中央,或者将它们提取到一个集中的文件中,以便到处共享。
  • 按钮被弃用,并创立了一个 ButtonNew 组件,决裂了代码库,引入了技术债权,并减少了入职学习曲线。

两种后果都不现实。

那么,” 按钮 ” 组件在哪里出了问题?

分享是一种侵害

HTML button 元素的职责到底是什么?放大这个答案将照亮之前 Button 组件所面临的问题。

原生的 HTML button 元素的职责不过如此:

  1. 显示,没有意见,无论什么内容被传入它。
  2. 解决本地性能和属性,如 onClickdisabled

是的,每个浏览器对按钮元素的外观和显示内容都有本人的版本,但 CSS 重置通常被用来剥夺这些意见。因而,按钮元素归根结底只是一个用于触发事件的功能性容器而已。

对按钮内的任何内容进行格式化不是按钮的责任,而是内容自身的责任。按钮不应该关怀。按钮不应该分担对其内容的责任。

体贴的组件设计的外围问题是,组件 prop 定义了内容而不是组件自身。

在以前的 Button 组件中,第一个次要限度是 text prop。从第一次迭代开始,就对 Button 的内容进行了限度。尽管 text prop 合乎那个阶段的设计,但它立刻偏离了本地 HTML 按钮的两个外围职责。它立刻迫使 Button 意识到并对其内容负责。

在接下来的迭代中,图标被引入。尽管在 Button 中退出一个有条件的图标仿佛很正当,但这样做也偏离了按钮的外围职责。这样做限度了该组件的应用状况。在起初的迭代中,图标须要在不同的地位可用,而 Button 的 prop 也被迫扩大到图标的款式。

当组件对它所显示的内容负责时,它须要一个能适应所有内容变动的 API。最终,这个 API 将被突破,因为内容将永远永远地扭转。

介绍一下团队中的我 #。

在所有团队静止中都有一句格言:” 团队中没有 ’ 我 '”。尽管这种心态很崇高,但一些最平凡的集体运动员却体现了其余想法。

迈克尔 - 乔丹用他本人的观点做出了驰名的回应:” 胜利中有一个 ’ 我 '”。已故的科比 - 布莱恩特也有相似的想法,”[团队]里有一个 ’M-E'”。

咱们最后的 Button 组件是一个团队成员。它分担了其内容的责任,直到它达到废除的境地。按钮如何通过体现 “ 团队中的 M -E “ 的态度来防止这种限度?

我,我本人,还有 UI

当组件对它所显示的内容负责时,它就会解体,因为内容将永远永远地扭转。

一个自私的组件设计办法会如何扭转咱们最后的按钮?

牢记 HTML 按钮元素的两个外围职责,咱们的 Button 组件的构造会立刻发生变化。

// 首先,从 React 扩大原生 HTML 按钮属性,如 onClick 和 disabled
type ButtonProps = React.ComponentPropsWithoutRef<"button"> & {theme: 'primary' | 'secondary' | 'tertiary';}
<Button
  onClick={someFunction}
  theme="primary"
>
  <span>Add to cart</span>
</Button>

通过去掉原来的 text prop 来代替有限的 children,Button 可能与它的外围职责保持一致。当初,Button 能够作为一个触发事件的容器而已。

通过将 Button 转移到反对子内容的本地办法,不再须要各种与图标相干的道具。当初,一个图标能够在 Button 的任何中央出现,无论其大小和色彩如何。兴许各种与图标相干的道具能够被提取到他们本人的自私的 Icon 组件中。

<Button
  onClick={someFunction}
  theme="primary"
>
  <Icon name="cart" />
  <span>Add to cart</span>
</Button>

随着特定内容的 prop 从 Button 中移除,它当初能够做所有自私的角色最善于的事件,即思考本人。

// First, extend native HTML button attributes like onClick and disabled from React.
type ButtonProps = React.ComponentPropsWithoutRef<"button"> & {
  size: 'sm' | 'md' | 'lg';
  theme: 'primary' | 'secondary' | 'tertiary';
  variant: 'ghost' | 'solid' | 'outline' | 'link'
}

有了专门针对本身的 API 和独立的内容,Button 当初是一个可保护的组件。本身的 props 使学习曲线最小化和直观化,同时为各种 Button 的应用案例保留了极大的灵活性。

按钮图标当初能够搁置在内容的两端:

<Button
  onClick={someFunction}
  size="md"
  theme="primary"
  variant="solid"
>
  <Box display="flex" gap="2" alignItems="center">
    <span>Add to cart</span>
    <Icon name="cart" />
  </Box>
</Button>

或者,一个 Button 能够只有一个图标:

<Button
  onClick={someFunction}
  size="sm"
  theme="secondary"
  variant="solid"
>
  <Icon name="cart" />
</Button>

然而,一个产品可能会随着工夫的推移而演变,而自私的组件设计能够进步与之一起演变的能力。让咱们超过 Button,进入自私的组件设计的基石。

自私设计的要害

与发明一个虚构的人物时一样,最好是向读者展现,而不是通知他们,他们是自私的。通过浏览人物的思维和口头,能够理解他们的共性和特色。组件设计也能够采取同样的办法。

然而,咱们到底如何在一个组件的设计和应用中表明它是自私的?

HTML 驱动组件设计

很多时候,组件是作为本地 HTML 元素的间接形象而构建的,比方 buttonimg。在这种状况下,让本地 HTML 元素来驱动组件的设计。

具体来说,如果本地 HTML 元素承受子元素,那么形象的组件也应该承受。一个组件的每一个方面如果偏离了它的原生元素,就必须重新学习。

当咱们最后的 Button 组件因为不反对子内容而偏离了按钮元素的原生行为时,它不仅变得生硬,而且须要转变思维模式能力应用该组件。

在 HTML 元素的构造和定义方面,曾经投入了大量的工夫和精力。轮子不须要每次都被从新创造。

children 自食其力

如果你读过《蝇王》,你就晓得当一群孩子被迫自食其力时,会有多危险。然而,在自私的组件设计案例中,咱们要做的正是这样。

正如咱们最后的 Button 组件所显示的那样,它越是试图对其内容进行款式设计,它就越是生硬和简单。当咱们去掉这个责任时,这个组件就能做得更多,但却少了很多。

许多元素只不过是语义上的容器而已。咱们并不常常冀望一个章节元素可能为其内容提供款式。一个按钮元素只是一个十分非凡的语义容器类型。当把它形象为一个组件时,同样的办法能够实用。

组件是繁多的重点

把自私的组件设计设想成安顿一堆蹩脚的第一次约会。一个组件的 prop 就像齐全以他们和他们的间接责任为核心的对话。

我看起来怎么样?

prop 须要满足组件的自我要求。在咱们重构的 Button 例子中,咱们用大小、主题和变体等 prop 做到了这一点。

我在做什么?

一个组件应该只对它,而且是它本人正在做的事件感兴趣。同样,在咱们重构的 Button 组件中,咱们用onClick prop 来做这个。就 Button 而言,如果在其内容的某个中央有另一个点击事件,那是内容的问题。按钮并不关怀。

我的下一站是什么时候,在哪里?

任何喷射性的旅行者都会很快议论他们的下一个目的地。对于像模态、抽屉和工具提醒这样的组件来说,它们何时何地也同样重要。像这样的组件并不总是在 DOM 中出现的。这意味着,除了晓得它们的外观和作用之外,它们还须要晓得何时何地。换句话说,这能够用 isShownposition这样的 props 来形容。

构图为王

一些组件,如模版和抽屉,往往能够蕴含不同的布局变动。例如,有些模版会显示一个标题栏,而其余模版则没有。一些抽屉可能有一个带有口头呐喊的页脚。其余的可能基本没有页脚。

与其在单个模态或抽屉组件中用条件 props(如 hasHeadershowFooter)定义每个布局,不如将单个组件分解成多个可组合的子组件。

<Modal>
  <Modal.CloseButton />
  <Modal.Header> ... </Modal.Header>
  <Modal.Main> ... <Modal.Main>
</Modal>
<Drawer>
  <Drawer.Main> ... </Drawer.Main>
  <Drawer.Footer> ... </Drawer.Footer>
</Drawer>

通过应用组件组合,每个独自的组件能够像它想的那样自私,只在须要的时候和中央应用。这样能够放弃根组件的 API 洁净,并且能够将许多 prop 转移到它们特定的子组件上。

当回顾咱们的 Button 组件的演变时,兴许自私的设计的要害是有意义的。然而,让咱们再把它们利用到另一个普遍存在问题的组件 – 模态。

对于这个例子,咱们在三个不同的模态布局中失去了预见性的益处。这将有助于疏导咱们 Modal 的方向,同时沿途利用自私设计的每个要害。

首先,让咱们回顾一下咱们的心理模型,并合成每个设计的布局。

在 “Edit Profile” 模式中,有定义的页眉、主页和页脚局部。也有一个敞开按钮。在 Upload Successful 中,有一个批改过的页眉,没有敞开按钮和一个相似英雄的图像。页脚的按钮也被拉长了。最初,在 Friends 模态中,敞开按钮返回,但当初内容区能够滚动,而且没有页脚。

那么,咱们学到了什么?

咱们理解到,页眉、主页和页脚局部是能够调换的。它们可能存在于任何给定的视图中,也可能不存在。咱们还理解到,敞开按钮的性能是独立的,不与任何特定的布局或局部相分割。

因为咱们的 Modal 能够由可调换的布局和安顿组成,这就是咱们采取可组合的子组件办法的标记。这将使咱们可能依据须要在模态中插入和播放部件。

这种办法容许咱们十分狭窄地定义咱们的根 Modal 组件的职责。

有条件地以任何内容布局的组合进行渲染。

这就是了。只有咱们的 Modal 只是一个有条件渲染的容器,它就永远不须要关怀或对其内容负责。

随着咱们的模态的外围职责被定义,以及可组合的子组件办法被决定,让咱们来合成每个可组合的局部和它的作用。

组成部分 角色
<Modal> 这是整个 Modal 组件的入口点。这个容器负责何时何地渲染,模态的外观,以及它所做的事件,比方解决可拜访性的思考。
<Modal.CloseButton /> 一个可调换的 Modal 子组件,只有在须要的时候才能够蕴含。这个组件的工作形式相似于咱们重构的 Button 组件。它将负责它的外观,显示的地位,以及它的作用。
<Modal.Header> 题目局部将是本地 HTML 题目元素的一个形象。它只不过是一个语义容器,用于显示任何内容,如题目或图片。
<Modal.Main> 主局部将是本地 HTML 主元素的一个形象。它只不过是任何内容的一个语义容器而已。
<Modal.Footer> 页脚局部将是本地 HTML 页脚元素的一个抽象化。它只不过是任何内容的一个语义容器而已。

有了每个组件及其角色的定义,咱们能够开始创立道具来反对这些角色和责任。

Modal

咱们定义了 Modal 的根本职责,即晓得何时有条件地渲染。这能够通过 isShown 这样的 prop 来实现。因而,咱们能够应用这些 prop,只有它是 true`,Modal 和它的内容就会渲染。

type ModalProps = {isShown: boolean;}
<Modal isShown={showModal}>
  ...
</Modal>

任何造型和定位都能够间接用 CSS 在 Modal 组件中实现。目前不须要创立特定的 prop。

Modal.CloseButton

鉴于咱们之前重构的 Button 组件,咱们晓得 CloseButton 应该如何工作。咱们甚至能够用咱们的 Button 来构建咱们的 CloseButton 组件。

import {Button, ButtonProps} from 'components/Button';

export function CloseButton({onClick, ...props}: ButtonProps) {
  return (<Button {...props} onClick={onClick} variant="ghost" theme="primary" />
  )
}
<Modal>
  <Modal.CloseButton onClick={closeModal} />
</Modal>

Modal.Header, Modal.Main, Modal.Footer

每个独自的布局局部,Modal.HeaderModal.MainModal.Footer,都能够从它们的 HTML 等价物,即headermainfooter中获取方向。这些元素中的每一个都反对子内容的任何变动,因而,咱们的组件也会这样做。

不须要非凡的 prop。它们只是作为语义容器。

<Modal>
  <Modal.CloseButton onClick={closeModal} />
  <Modal.Header> ... </Modal.Header>
  <Modal.Main> ... </Modal.Main>
  <Modal.Footer> ... </Modal.Footer>
</Modal>

有了咱们的 Modal 组件和它的子组件的定义,让咱们看看它们是如何被调换应用来创立这三种设计的。

留神:残缺的标记和款式没有显示进去,以便不影响外围的播种。

EDIT PROFILE MODAL

在 Edit Profile 模态中,咱们应用了每个 Modal 组件。然而,每一个都只是作为一个容器,它的款式和地位都是本人的。这就是为什么咱们没有为它们蕴含一个className prop。任何内容的款式都应该由内容自身来解决,而不是咱们的容器组件。

<Modal>
  <Modal.CloseButton onClick={closeModal} />

  <Modal.Header>
    <h1>Edit Profile</h1>
  </Modal.Header>

  <Modal.Main>
    <div className="modal-avatar-selection-wrapper"> ... </div>
    <form className="modal-profile-form"> ... </form>
  </Modal.Main>

  <Modal.Footer>
    <div className="modal-button-wrapper">
      <Button onClick={closeModal} theme="tertiary">Cancel</Button>
      <Button onClick={saveProfile} theme="secondary">Save</Button>
    </div>
  </Modal.Footer>
</Modal>

UPLOAD SUCCESSFUL MODAL

像后面的例子一样,Upload Successful 模态应用其组件作为无意见的容器。内容的款式是由内容自身解决的。兴许这意味着按钮能够被 modal-button-wrapper 类拉伸,或者咱们能够给 Button 组件增加一个 ” 我看起来怎么样?” 的道具,比 如 isFullWidth,以取得更宽或全宽的尺寸。

<Modal>
  <Modal.Header>
    <img src="..." alt="..." />
    <h1>Upload Successful</h1>
  </Modal.Header>

  <Modal.Main>
    <p> ... </p>
    <div className="modal-copy-upload-link-wrapper"> ... </div>
  </Modal.Main>

  <Modal.Footer>
    <div className="modal-button-wrapper">
      <Button onClick={closeModal} theme="tertiary">Skip</Button>
      <Button onClick={saveProfile} theme="secondary">Save</Button>
    </div>
  </Modal.Footer>
</Modal>

FRIENDS MODAL

最初,咱们的 Friendsmodal 勾销了 Modal.Footer 局部。在这里,在 Modal.Main 上定义溢出款式可能很迷人,但这是将容器的责任扩大到它的内容。相同,解决这些款式在 modal-friends-wrapper 类中更适合。

<Modal>
  <Modal.CloseButton onClick={closeModal} />

  <Modal.Header>
    <h1>AngusMcSix's Friends</h1>
  </Modal.Header>

  <Modal.Main>
      <div className="modal-friends-wrapper">
        <div className="modal-friends-friend-wrapper"> ... </div>
        <div className="modal-friends-friend-wrapper"> ... </div>
        <div className="modal-friends-friend-wrapper"> ... </div>
      </div>
  </Modal.Main>
</Modal>

总结

本文对组件设计中的一个重要概念——自私性进行了探讨。自私性(Selfishness)在组件设计中是一种思维形式,意味着每个组件只关怀其本身的性能和款式,而不关怀其余组件。该文章认为,自私性能够帮忙开发者创立更高效、易于保护的组件。

文章论述了以下四个实际自私性的办法:

繁多职责准则:组件应该有一个明确的性能,并仅关注该性能。这使组件更容易了解、测试和复用。

防止内部依赖:组件应该缩小对外部资源的依赖,这有助于进步组件的独立性和复用性。

封装款式:组件的款式应该外部定义,防止受到内部款式影响。这样做能够确保组件在不同的环境中放弃一致性。

明确接口:组件应该具备清晰、明确的接口,以便其余开发者可能容易地理解和应用组件。

作者强调,自私性并不意味着开发者应该孤立地工作,而是激励他们关注组件自身,从而进步组件的品质。通过遵循上述准则,开发者能够创立更加强壮、可保护和可扩大的组件,为整个我的项目带来久远的益处。

代码部署后可能存在的 BUG 没法实时晓得,预先为了解决这些 BUG,花了大量的工夫进行 log 调试,这边顺便给大家举荐一个好用的 BUG 监控工具 Fundebug。

原文:https://www.smashingmagazine.com/2023/01/key-good-component-d…

交换

有幻想,有干货,微信搜寻 【大迁世界】 关注这个在凌晨还在刷碗的刷碗智。

本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试残缺考点、材料以及我的系列文章。

正文完
 0