可以看到,为了表示现实世界中人(这里其实指的是员工的概念)、工程师、销售员、经理的概念,代码根据人的自然观点设计了继承层次结构,并很好的实现了重用。而且,我们可以认定该接口是相对稳定的。我们再来看看实现部分:
public class PersonImpFlag implements Person, Salesman, Engineer,Manager{
// Implementing Salesman
public static Salesman newSalesman (String name){
PersonImpFlag result;
result = new PersonImpFlag (name);
result.makeSalesman();
return result;
};
public void makeSalesman () {
_jobTitle = 1;
};
public boolean isSalesman () {
return _jobTitle == 1;
};
public void numberOfSales (int value){
requireIsSalesman () ;
_numberOfSales = value;
};
public int numberOfSales () {
requireIsSalesman ();
return _numberOfSales;
};
private void requireIsSalesman () {
if (! isSalesman()) throw new PreconditionViolation ("Not a Salesman") ;
};
private int _numberOfSales;
private int _jobTitle;
}
这是其中一种被称为内部标示(Internal Flag)的实现方法。这里我们只是举出一个例子,实际上我们还有非常多的解决方法,但我们并不关心。因为只要接口足够稳定,内部实现发生再大的变化都是允许的。如果对实现的方式感兴趣,可以参考Matrin Fowler的角色建模的文章或是我在阅读这篇文章的一篇笔记。 通过上面的例子,我们可以了解到,接口和实现分离的最大好处就是能够在客户端未知的情况下修改实现代码。这个特性对于分层技术是非常适用的。一种是用在层和层之间的调用。层和层之间是最忌讳耦合度过高或是改变过于频繁的。设计优秀的接口能够解决这个问题。另一种是用在那些不稳定的部分上。如果某些需求的变化性很大,那么定义接口也是一种解决之道。举个不恰当的例子,设计良好的接口就像是我们日常使用的万用插座一样,不论插头如何变化,都可以使用。
最后强调一点,良好的接口定义一定是来自于需求的,它绝对不是程序员绞尽脑汁想出来的。