原文
https://www.jianshu.com/p/1a0a0a74769a
大纲
综述
1、单一职责
2、命名
3、LIFT-D应用程序结构
4、组件
综述
以下说的准则是根据angular官网的风格指南总结归纳而出的,使用angular框架进行项目开发,有准则和没有准则的体验是完全不同的,有准则的体验会给开发者更舒服,更严谨的开发体验,并且根据相同的准则开发可以避免很多冲突以及不可预料的问题。
1、单一职责
1.1、对所有的组件、服务等等应用单一职责原则 (SRP)
坚持每个文件只定义一样东西(例如服务或组件)。
考虑把文件大小限制在 400 行代码以内。
1.2、坚持定义简单函数
坚持定义简单函数。
考虑限制在 75 行之内。
简单函数更易于测试,特别是当它们只做一件事,只为一个目的服务时。
2、命名
2.1、坚持统一的命名模式和规则
坚持所有符号使用一致的命名规则。
坚持遵循同一个模式来描述符号的特性和类型。坚持遵循先描述组件特性,再描述它的类型的模式,对所有组件使用一致的类型命名规则。推荐的模式为feature.type.ts。
坚持使用惯用的后缀来描述类型,包括.service、.component、*.pipe、.module、.directive。 必要时可以创建更多类型名,但必须注意,不要创建太多。
2.2、使用点和横杠来分隔文件名
坚持 在描述性名字中,用横杠来分隔单词。
坚持使用点来分隔描述性名字和类型。
2.3、统一的符号名与文件名的命名约定
坚持为所有东西使用一致的命名约定,以它们所代表的东西命名。
坚持使用大写驼峰命名法来命名类。符号名匹配它所在的文件名。
坚持在符号名后面追加约定的类型后缀(例如Component, Directive, Module, Pipe, or Service)。
坚持在文件名后面追加约定的类型后缀(例如.component.ts、.directive.ts、.module.ts、.pipe.ts、.service.ts)。
2.4、服务名
坚持使用一致的规则命名服务,以它们的特性来命名。
坚持为服务的类名加上Service后缀。 例如,获取数据或英雄列表的服务应该命名为DataService或HeroService。
有些词汇显然就是服务,比如那些以“-er”后缀结尾的。比如把记日志的服务命名为Logger就比LoggerService更好些。需要在你的项目中决定这种特例是否可以接受。 但无论如何,都要尽量保持一致。
2.5、main.ts(引导)
坚持把应用的引导程序和平台相关的逻辑放到名为main.ts的文件里。
坚持在引导逻辑中包含错误处理代码。
避免把应用逻辑放在main.ts中,而应放在组件或服务里。
2.6、指令选择器
坚持使用小驼峰命名法来命名指令的选择器。
2.7、为组件添加自定义前缀
坚持使用带连字符的小写元素选择器值(例如 admin-users)
坚持为组件选择器添加自定义前缀。 例如,toh 前缀表示 Tour of Heroes(英雄指南),而前缀 `admin 表示管理特性区。
坚持使用前缀来识别特性区或者应用程序本身。
为什么要坚持为组件添加自定义前缀:
a:防止与其它应用中的组件和原生 HTML 元素发生命名冲突。
b:更容易在其它应用中推广和共享组件。
c:组件在 DOM 中更容易被区分出来。
2.8、为指令添加自定义前缀
坚持为指令的选择器添加自定义前缀(例如前缀 toh 来自 Tour of Heroes)。
坚持用小驼峰形式拼写非元素选择器,除非该选择器用于匹配原生 HTML 属性。
为什么要坚持为组件添加自定义前缀。
a:防止名字冲突。
b:指令更加容易被识别。
2.9、管道名
坚持为所有管道使用一致的命名约定,用它们的特性来命名。
提供一致方式快速识别和引用管道。
2.10、模块名
坚持为符号名添加 Module 后缀
坚持为文件名添加 .module.ts 扩展名。
坚持用特性名和所在目录命名模块。
为什么要坚持统一标准的模块名:
a:提供一致的方式来快速标识和引用模块。
b:大驼峰命名法是一种命名约定,用来标识可用构造函数实例化的对象。
b:很容易就能看出这个模块是同名特性的根模块。
坚持为 RoutingModule 类名添加 RoutingModule 后缀。
坚持为 RoutingModule 的文件名添加 -routing.module.ts 后缀。
为什么要坚持统一标准的路由模块名:
a:RoutingModule 是一种专门用来配置 Angular 路由器的模块。
b:“类名和文件名保持一致”的约定使这些模块易于发现和验证。
3、LIFT-D应用程序结构
坚持组织应用的结构,达到这些目的:快速定位 (Locate) 代码、一眼识别 (Identify) 代码、 尽量保持扁平结构 (Flattest) 和尝试 (Try) 遵循 DRY (Do Not Repeat Yourself, 不重复自己) 原则。
坚持四项基本原则定义文件结构,上面的原则是按重要顺序排列的。
3.1、定位(Locate)
坚持直观、简单和快速地定位代码。
为何? 要想高效的工作,就必须能迅速找到文件,特别是当不知道(或不记得)文件名时。 把相关的文件一起放在一个直观的位置可以节省时间。 富有描述性的目录结构会让你和后面的维护者眼前一亮。
3.2、识别(Identify)
坚持命名文件到这个程度:看到名字立刻知道它包含了什么,代表了什么。
坚持文件名要具有说明性,确保文件中只包含一个组件。
避免创建包含多个组件、服务或者混合体的文件。
为何?花费更少的时间来查找和琢磨代码,就会变得更有效率。 较长的文件名远胜于较短却容易混淆的缩写名。
3.3、扁平(Flattest)
坚持尽可能保持扁平的目录结构。
考虑当同一目录下达到 7 个或更多个文件时创建子目录。
考虑配置 IDE,以隐藏无关的文件,例如生成出来的 .js 文件和 .js.map 文件等。
为何?没人想要在超过七层的目录中查找文件。扁平的结构有利于搜索。另一方面,心理学家们相信, 当关注的事物超过 9 个时,人类就会开始感到吃力。 所以,当一个文件夹中的文件有 10 个或更多个文件时,可能就是创建子目录的时候了。还是根据你自己的舒适度而定吧。 除非创建新文件夹能有显著的价值,否则尽量使用扁平结构。
3.4、T-DRY(尽量不重复自己)
坚持 DRY(Don't Repeat Yourself,不重复自己)。
避免过度 DRY,以致牺牲了阅读性。
为何?虽然 DRY 很重要,但如果要以牺牲 LIFT 的其它原则为代价,那就不值得了。 这也就是为什么它被称为 T-DRY。 例如,把组件命名为 hero-view.component.html 是多余的,因为带有 .html 扩展名的文件显然就是一个视图 (view)。 但如果它不那么显著,或不符合常规,就把它写出来。
4、组件
4.1、坚持使用中线 (dashed) 命名法或烤串 (kebab) 命名法来命名组件中的元素选择器。
4.2 、把模板和样式提取到它们自己的文件
4.3、内联输入和输出属性装饰器
坚持 使用 @Input() 和 @Output(),而非 @Directive 和 @Component 装饰器的 inputs 和 outputs 属性:
坚持把 @Input() 或者 @Output() 放到所装饰的属性的同一行。
易于在类里面识别哪些属性是输入属性或输出属性。
如果需要重命名与 @Input 或者 @Output 关联的属性或事件名,你可以在一个位置修改。
依附到指令的元数据声明会比较简短,更易于阅读。把装饰器放到同一行可以精简代码,同时更易于识别输入或输出属性。
4.4、避免为输入和输出属性指定别名
避免除非有重要目的,否则不要为输入和输出指定别名。
同一个属性有两个名字(一个对内一个对外)很容易导致混淆。
如果指令名也同时用作输入属性,而且指令名无法准确描述这个属性的用途时,应该使用别名。
4.5、成员顺序
坚持把属性成员放在前面,方法成员放在后面。
坚持先放公共成员,再放私有成员,并按照字母顺序排列。
把类的成员按照统一的顺序排列,易于阅读,能立即识别出组件的哪个成员服务于何种目的。
4.6、把逻辑放到服务里
坚持在组件中只包含与视图相关的逻辑。所有其它逻辑都应该放到服务中。
坚持把可重用的逻辑放到服务中,保持组件简单,聚焦于它们预期目的。
当逻辑被放置到服务里,并以函数的形式暴露时,可以被多个组件重复使用。
在单元测试时,服务里的逻辑更容易被隔离。当组件中调用逻辑时,也很容易被模拟。
从组件移除依赖并隐藏实施细节。
保持组件苗条、精简和聚焦。
4.7、不要给输出属性加前缀
坚持命名事件时,不要带前缀 on。
坚持把事件处理器方法命名为 on 前缀之后紧跟着事件名。
与内置事件命名一致,例如按钮点击。
Angular 允许另一种备选语法 on-*。如果事件的名字本身带有前缀 on,那么绑定的表达式可能是 on-onEvent。
4.8、把表现层逻辑放到组件类里
坚持把表现层逻辑放进组件类中,而不要放在模板里。
逻辑应该只出现在一个地方(组件类里)而不应分散在两个地方。
将组件的表现层逻辑放到组件类而非模板里,可以增强测试性、维护性和重复使用性。