任何傻瓜都可以写出计算机能懂的代码,但好的程序员可以写出人类能懂的代码-----Martin Fowler

如果你是新手,你可能会问,为什么代码需要设计原则?我想说的是肯定不是为了故作高深,存在即是合理,如果写了一个简单的程序,你可能不需要设计原则,如果你写了一个复杂的,但是之后再也不会改,那么你也不需要,但是现实生活中,基本上的软件系统有一定复杂度,而且都在不断的修改。所以我们需要写出一个不仅让机器看懂,还能够让人类看懂的代码。让人类能看懂的代码即是可维护性代码,它包含两个核心原则:高内聚、低耦合。

一个有助于实现高内聚低耦合的原则是关注点分离Separation of Concerns(SOC),关注点是软件功能的不同部分,像业务逻辑或者表现方式,SOC是关于把系统分解成不同的可能没有重叠的特性,比如尽量将业务逻辑放在领域层,而不是一部分放在存储过程,一部分放在UI。后来这些原则得到进一步的完善和强化,大师Robert C. Martin给出了5个更有效,更具体和可实施的原则,即比较流行的SOLID原则。

  1. 单一职责(SRP) 类应该尽可能简单,专注于一个核心任务。
  2. 开闭原则(OCP) 即对扩展开放,对修改关闭。
  3. 里氏替换原则(LSP) 子类可以替换他们的基类。
  4. 接口分离原则(ISP) 接口隔离原则解决的是接口臃肿的问题,建议保持接口最低限度的函数。
  5. 依赖反转原则(DIP) 即高级模块不应该依赖于低层模块,二者都应该依赖于抽象,什么意思呢,比如说你在开发asp.net MVC, Controller里需要访问某个服务或者数据库层,最好不要直接在controller里直接引用相关的实现类,而应该引用相关的服务和持久层的抽象,一般是相应的接口,通用的做法是使用IOC组件来做这个事情,如Unity,Autofac等。

除此以外,还有一些比较实用的原则:

  1. DRY(Don't Repeat Yourself)
  2. 说,别问(Tell,Don't Ask) 总的来说,这是对象建模的启蒙原则,就OOP而言,创建软件实体可以包含数据并暴露某些行为,意思是你在实现某个功能的时候,避免请求数据并在某个外围逻辑容器里处理,举个例子,比如一个订单聚合根,计算订单的价格只需要通过聚合根内的一个方法获取就好了,不需要你在订单聚合根意外的别的其他地方获取订单项再重新计算一遍了。
  3. KISS(keep It Simple,Stupid) 法国诗人曾说,完美不是没有东西可以增加,而是没有东西可以减少,在软件开发里,是为了防止过渡设计的情况发生。
  4. YAGNI(You Ain't Gonna Need It) 这个原则认为实现需求上没有提到的任何功能都是有问题的,即在你认为自己可能需要而不是实际需要时实现一个函数可能会给你带来一些潜在的问题。

说了这么多如何写出好的代码?

写出好的代码,不是每个人天生就会的,他需要一个过程,一个重构的过程,实际工作上,重构是每天都会发生的,你重构代码不是因为他不工作了,而是为了更好的实现某些非功能性需求,如可读性,可维护性,可测试性或可扩展性,或者为了提高性能。

常见的重构操作:

  1. 提取方法
  2. 提取接口
  3. 封装字段
  4. 重命名
  5. 使用新的组件代替旧的组件