软件是变化的,这些变化包含需求变化,设计变化,Bug修改等等,为了避免牵一发而动全身,我们就需要降低系统的耦合。
在不同的层面解耦的方法不一样,但主要思想还是一致的,都是通过接口将变化屏蔽到一定的范围内。这里的接口是一个广义的接口,它指一种规范。
在面向接口的编程中,对象和对象之间通过接口来互相访问,只要接口不变,对象之间就不会相互影响。变化被屏蔽在对象的内部。
在分层的系统中,我们通过接口来实现层层之间的访问,变化被屏蔽在层内部。
但这样还不够,实例化对象时还是有耦合的,于是IOC诞生了,通过配置文件来装配对象。这样实例化对象的是通过配置文件来配置的,由容器来完成的。
在另一方向上,为了将业务和其它分离开,如日志,异常,缓存,事务等等,AOP诞生了,它将一个个方面分离开来,这也是一种解耦。在这种剥离下,简单的Java对象(Plain Old Java Object)诞生下,这种对象是不依赖于框架即继承或实现某些框架类和接口。它是一个简单的、正规Java对象,它包含业务逻辑处理或持久逻辑等。.net也在做这种分离,在WCF中,我们编写业务处理类,而通过配置文件来配置具体的通讯协议,将业务类和通讯方式分离。
在更高的层次上,Java或者.net通过虚拟机来屏蔽不同的操作系统之间的差异(mono支持下,net也能跨平台,其实这两种语言的设计都是跨语言跨平台的)。对于不同的操作系统,虚拟机提供相同的接口,我们通过字节码或者MSIL(Microsoft Intermediate Language)来操作虚拟机,字节码或者MSIL就是一种规范,也可以说是一种接口。
其实,不仅仅在软件设计上,降低耦合是在你身边所有的地方。如圆珠笔的笔芯,我们用完以后可以换掉,只要符合这支笔的接口的笔芯就可以;电池用完了,只要用同接口(型号)的电池替换就行了;计算机网卡坏了,换个符合接口的网卡就可以了。
耦合降低了,每次的改动影响范围减少了,代码的复用率增高了,BUG也少了,系统也更稳定了。