软件设计原则和编码规范

目录

  • 软件设计原则和编码规范
    • 软件设计
    • 软件实现与编码规范
      • 命名
      • 重构
        • 函数
        • 注释
      • 单元测试

软件设计原则和编码规范

软件设计

  1. 单一职责原则(Single Responsibility Principle :SRP)

    一个类或者模块只负责完成一个职责(或者功能)。

    何时拆分代码:

    ? 1. 类中代码行数、属性、函数过多,影响代码可读性和可维护性

    1. 类依赖的其他类过多
    2. 私有方法过多
    3. 难以给类起一个准确的命名
    4. 大量的方法都是集中在某几个属性时
  2. 开闭原则(Open Closed Principle :OCP)

    扩展开放,对修改关闭。

    添加一个新的功能应该是,在已有代码基础上扩展代码(新增模块、类、方法等),而非修改已有代码(修改模块、类、方法等)。

    代码的扩展性是代码质量评判的最重要的标准之一,常用的设计模式几乎都是为了代码的可扩展性服务。我们要时刻具备扩展意识、抽象意识、封装意识。在写代码的时候,我们要多花点时间思考一下,这段代码未来可能有哪些需求变更,如何设计代码结构,事先留好扩展点,以便在未来需求变更的时候,在不改动代码整体结构、做到最小代码改动的情况下,将新的代码灵活地插入到扩展点上。

  3. 里氏替换原则(Liskov Substitution Principle :LSP)

    子类对象(object of subtype/derived class)能够替换程序(program)中父类对象(object of base/parent class)出现的任何地方,并且保证原来程序的逻辑行为(behavior)不变及正确性不被破坏。

  4. 接口隔离原则(Interface Segregation Principle :ISP)

    Clients should not be forced to depend upon interfaces that they do not use.

    客户端不应该被强迫依赖它不需要的接口。

    不同“接口”环境下的解读:

    1. 一组 API 接口集合

      隔离不需要的API——“我”不需要的不要暴露给我

    2. 单个 API 接口或函数

      函数功能需要单一——“我”不需要的功能不要给我

    3. OOP 中的接口概念

      职能划分单一

  5. 依赖反转原则(Dependency Inversion Principle :DIP)

    高层模块(high-level modules)不要依赖低层模块(low-level)。高层模块和低层模块应该通过抽象(abstractions)来互相依赖。除此之外,抽象(abstractions)不要依赖具体实现细节(details),具体实现细节(details)依赖抽象(abstractions)。

    所谓高层模块和低层模块的划分,简单来说就是,在调用链上,调用者属于高层,被调用者属于低层。

  6. KISS(Keep It Short and Simple.)

  7. YAGNI(You Ain’t Gonna Need It)

    适可而止

  8. DRY(Don’t Repeat Yourself )

  9. 迪米特法则(Law of Demeter)

    The Least Knowledge Principle。

    最小知识原则

软件实现与编码规范

命名

  1. 变量命名

    1. 名副其实——变量名应该具有较为明确的意义、语义

    2. 避免误导

      避免留下掩藏代码本意的错误线索。

      例如使用accountList,由于List本身具有特殊含义,如果该容器并非是一个真正的List,那么会引起错误的判断。相较之下使用accounts也许会更好。

    3. 命名可读性

      避免使用拼音简写、肆意的英文简写或拼音+英文混合的命名方法。错误示范:fiveXing——五行、左和右——leftAndYou、数组命名——array、brray

    4. 命名可搜索

      只有以相同的方式得到同样的结果才能称之为信息——注意命名约定

      有意义的命名区分——对于相近的内容,在命名上应当具有有意义的区分。例如,GUI编程中,不建议使用——panel1、panel2等。

  2. 类命名

    类名和对象名应是名词或名词短语——例如,Customer、WikiPage、AddressParser。避免使用——例如,Manager、Processor等过于宽泛的名词。

    类名不应当是动词。

  3. 函数/方法命名

    方法或函数命名应当是动词或动词短语,例如,PostPayment、deletePage。

    访问、修改和断言应当加上getsetis前缀,例如,getName、setAge、isEmpty等。

重构

函数

  1. 函数应当是短小的

    函数过长不利于上下文记忆,同样不利于调试。

    如果某一段代码片段具有一个较为明确的目的,那么应该考虑将其提炼成一个函数

  2. 函数只需要做一件事,只需要做好一件事

  3. 函数中的语句都应该在同一抽象层——自顶向下写代码

  4. 控制函数参数,尽量不超过3个

注释

——注释并不能美化糟糕的代码
原则上应当使用代码进行阐述,不要过度依赖注释,无论是写代码还是读代码。
好的注释应当是具有一定抽象高度的——少写废话、少写显然易得的注释。
注释是代码的一部分,维护代码也需要维护注释

单元测试

单元测试是一小段代码,在特定上下文环境中,单元测试能够执行产品的一部分代码。

测试驱动开发(TDD)三定律:

  1. 在编写不能通过的单元测试前,不可编写生产代码——测试先行
  2. 只可编写刚好无法通过的单元测试——保证测试覆盖率
  3. 只可编写刚好足以通过当前失败测试的生产代码——YAGNI

单元测试的好处:保证代码可扩展、可维护、可复用——无惧修改

单元测试也应具有可读性

单元测试的命名应包含三部分:

  1. 单元测试的前置条件
  2. 被单元测试测试的部分
  3. 单元测试的预期结果

例如:

cacheIsEmpty_addElement_sizeIsOne()

良好的测试应该遵循的规则——快速、独立、可重复、自足验证、(编写)及时。

来源:程序猿D

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2020年10月14日
下一篇 2020年10月14日

相关推荐