这些是在Java里面看到的设计原理,在Net环境同样可以借鉴。
在开发的整个过程中,开发团队通常要花费大量时间来设计系统。但是大多数时间是花在创建一个灵活的类结构上,只有少部分时间被用来设计系统的包结构。包之间的关系通常不被考虑,将类如何分配到包也没有经过细致的思考。这种疏忽是不幸的,因为包之间的关系和类之间的关系一样重要。
如果类Client与类Service有关系,那么很明显,包含这两个类的包之间也应存在一定的关系,通常称之为“包的依赖”。
如果对P1包的内容的改变会影响到另一个包P2的内容,那么我们就说P1在P2上有一个包的依赖
1、版本重用等价原理(Release Reuse Equivalency Principle,REP)
我们知道,任何Java类可以只在一个包中。因此,如果想要使用一个类的服务,我们不仅必须引用这个类,而且也必须明确地引用其所在的包。如果不这么做将导致编译时错误。因此,为了使用一个类,我们必须确保其所在的包也被引用。
因为包被引用了,所以我们能够使用包中任何公共类所提供的服务。因此,当我们当前只需要包含包中的一个类的服务时,所有类的服务对于我们来说都是可用的。
因此,版本单元就是我们的重用单元,这就是版本重用等价原理。
2、通用闭包原理(Common Closure Principle,CCP)
类内聚强调了要创建功能完善而且不跨越职责界限的类。包内聚侧重于包内部的类,强调由整个包提供的所有服务。
在开发过程中,当对一个类的改变可能指示了对另一个类的改变时,最好两个类放在同一个包中。
CCP在概念上可能容易理解;但是应用它则比较困难,因为我们能够以这种方式将类分组在一起的唯一方法在于,我们能够预见将要发生的改变以及这些改变的结果会在哪些依赖类上产生影响
这种预见可能经常是不正确的或者不全面的,但不管怎样,将类放到各个包中应该经过深思熟虑。
3、通用重用原理(Common Reuse Principle,CreP)
如果一个类依赖于一个不同包中的其他一个类,那么它实际上依赖于那个包中的所有类,虽然引用是间接的。不能被一起重用的类不应该放在一起。类一起被重用与类一起被改变是两个不同的概念。
REP和CreP强调的是重用,而CCP强调的则是维护。
4、无环依赖原理(Acyclic Dependencies Principle,ADP)
应该尽量避免形成一个应用的包的环形依赖。换句话说,包应该形成一个有向无环图(Directed Acyclic Graph,DAG)。
环形依赖导致不同包中的类是耦合的,所以这些不同的包变成紧密耦合。它会对REP产生消极的影响以至于所有这些类都必须在同一个包中,但这样一来,CCP也被严重影响了。
如果我们确实确定有环形依赖,最简单的解决办法是找出导致这种依赖结构的类,把它们放到一个单独的包中。
5、稳定依赖原理(Stable Dependencies Principle,SDP)
稳定性是一种表示系统忍受变化的容易程度的特点,在Java中,我们更关心包的弹性。
那些可能不断发生改变的包是不太稳定的,这就意味着它拥有较少的外部调用依赖性,较多的调用外部依赖性。
那些不太经常发生变化的包是比较稳定的,这就意味着它拥有更多的外部调用依赖性,较少的调用外部依赖性。
由于依赖关系的准则使得包可能是稳定的,也可能不够稳定,因此,很明显地,我们应该自然而然地依靠稳定性准则。任何产生的依赖性都应该是深思熟虑的结果,并且应该对整个应用的稳定性有着重要的影响。理想的,应该只在那些稳定的包中引入依赖性。
6、稳定抽象原理(Stable Abstraction Principle,SAP)
在包的层次结构中,不够稳定的包应出现在包层次中的顶层,而较稳定的包出现在包层次中的底层。基于这一点,一个处于包层次中较底层的包必须是更有弹性的包,这是很重要的,因为对这些包做改变会有很大的影响。
依靠稳定性准则,应该将抽象的类、接口放在更稳定的包中,这有助于确保那些依赖性较强的类拥有更高的稳定性。
包括许多抽象类和接口的更稳定的包应该被大量的依赖。
包括很多具体类的不够稳定的包不应该被大量的依赖。
稳定的包应该是抽象包。