面向对象设计十条诫律

编写干净代码,阻止丑陋的错误与坏味道,十条规则遵循如下:

1.遵循单一职责原则
每个类应该而且只有一种思考方向的变化,对类如此,对方法也是如此,那些冗长的无所不包的类或方法摊开在一张纸上的长度快要有中国长城长度的一半了。

每一个类或一个方法只有为一个理由存在。如果该类被称为贷款,那么它不应该处理银行帐户相关的细节。如果方法调用是getloandetails,那么它实则就是负责获得贷款的细节。

遵循开闭原则
思考你的系统如何适应未来的变化。开闭原则指出: 一个系统应该以最小改变的代价添加新的功能,对于拓展是开放,对于修改则是闭合,也就是少修改成熟的代码,多拓展扩展新代码。

比如:


public class PersonalLoan
{
public void Terminate()
{
//Execute Termination related rules here and terminate a personal loan
}
}
public class AutoLoan
{
public void Terminate()
{
//Execute Termination related rules here and terminate a personal loan
}
}
public class LoanProcessor
{
public void ProcessEarlyTermination(object loan)
{
if ( loan is PersonalLoan )
{
//Personal Loan processing
}
else if (loan is AutoLoan)
{
//Auto Loan Processing
}
}
}


loan贷款类型有两个类型PersonalLoan和AutoLoan,当有新的贷款类型时如HomeLoan, LoanProcessor 代码则需要修改,这是不推荐的,因为修改成熟经过测试的代码,会可能引入新的问题。

采取下面结构则可以将新的类型作为子对象进行扩展,也就是使用继承扩展来应付新的贷款类型增加,符合开闭原则:


public abstract class Loan
{
public abstract void Terminate();
}
public class PersonalLoan: Loan
{
public override void Terminate()
{
//Execute Termination related rules here and terminate a personal loan
}
}
public class AutoLoan: Loan
{
public override void Terminate()
{
//Execute Termination related rules here and terminate a personal loan
}
}
public class LoanProcessor
{
public void ProcessEarlyTermination(Loan loan)
{
loan.Terminate();
}
}

3.组合高于继承
如果没有正确的对现实模型的分析,草率使用继承会导致脆弱的类层次结构。其实很简单的,经常问-如果使用继承结构实现父子关系,反问自己:“子类是父类的一种类型吗?“或者“子类有某种父类类型吗?“

当你需要使用某个类的部分功能函数时,总是使用组合,因为使用继承就可能会在整个类型上与原始类绑定,绑定范围面积太大。如同男女上一次床就要结婚,这种绑定面积也是过大。

4.封装数据和行为
大多数开发人员只做数据封装,却忘记封装这些数据所处的上下文场景的代码。隐藏类的私有数据也很重要,更重要的是还要封装那些操作这些私有数据的行为方法。

5.类之间遵循松耦合
这是封装了正确行为后顺带的好处,如果行为被恰当封装到类中,类之间就能松耦合,通过相互依赖抽象而不是具体实现,才能实现松耦合。

6.使得类内部高度聚合
不应该将数据和行为分散在多个类中,努力方向之一是尽量不要使得实现细节分离或泄露到其他类中,也意味着类的代码不能超出其存在的目的,有一些设计范式如CQRS能让你分离不同的行为在不同的类中,但是它只适合分布式系统。

7.面向接口编程,而不是面向实现
这使得类自身任何底层细节改变或引入新的变化不会影响到这个类的使用者。

8.保持DRY 不要重复你自己
不要在两个不同的地方有重复相同的代码。一个特定的功能或算法只应在一个地方实现,多个地方重复实现会导致维护问题,其反义词被称为“湿”,任何东西写两次。

9.最少知识原则:迪米特法则
一个对象不应该知道与其交互的另外一个对象内部细节,一个类只能调用与它合作类的公共数据成员,如果不遵循会导致紧耦合,系统难以改变。

10.按照好莱坞的原则: 别给我们打电话,我们会打电话给你
这打破基于条件流逻辑的模型,能够允许代码基于事件执行,可以通过事件回调或注入一个接口的实现,依赖注入和反转控制是这种模式。

10 Commandments of Object-Oriented Design - DZone