举例说明:
电脑主板要工作就得依赖于CPU、内存、风扇、声卡、网卡等等,如果其中某个零部件坏了,那么需要把整个主板换掉么?当然不是。
下面的例子是展示 电脑主板和CPU、内存、风扇、声卡、网卡存在非常强耦合的例子
public class KeyBoard
{
private CPU cpu;
private Memeory memory;
private SoundCard soundCard;
public KeyBoard()
{
cpu = new CPU(); //依赖于具体类
memory = new Memeory(); //依赖于具体类
soundCard = new SoundCard(); //依赖于具体类
}
public void work()
{
cpu.work();
memory.work();
soundCard.work();
}
}
class CPU
{
public void work()
{
//CPU工作
}
}
class Memeory
{
public void work()
{
//内存工作
}
}
class SoundCard
{
public void work()
{
//声卡工作
}
}
正如前面的注释,由于KeyBoard依赖于具体的类,也就是主板依赖据特定型号的CPU,那么当CPU坏掉时,要更换另外一种型号的CPU,程序员要做的就是修改这个KeyBoard类,没有做到对修改关闭,对扩展开放。程序维护起来是相当麻烦的。所以就需要将KeyBoard类与具体类解耦,因为主板是相对稳定的,某个零部件有问题的话,不需要更换主板。如何解耦呢?KeyBoard类需要依赖于抽象类或者接口,因为这些东西都是稳定的,所以稳定的东西应该依赖于稳定的东西,不稳定的东西也应该依赖于稳定的东西,这个稳定的东西可以是抽象类,也可以是接口。
具体方法如下:将KeyBoard的零部件都抽象出来,CPU抽象出AbstractCPU,Memory抽象出AbstractMemory,当然其中必须有个多态的方法Work,这样每个子类再实现这些方法即可,在这里用到了依赖注入技术,可以通过构造函数注入,也可以通过第三方注入。
通过构造函数注入的方法如下:
public KeyBoard(AbstractCPU cpu, AbstractMemory memory, AbstractSoundCard soundCard)
{
this.cpu = cpu;
this.memory = memory;
this.soundCard = soundCard;
}
这样就实现了解耦,如果需求发生变化,这个KeyBoard类就不用修改,就不用更换主板了,需要做的是Client在调用的时候需要具体类的注入,Client调用如下:
class Client
{
private void work()
{
AbstractCPU cpu = new CPU(); //以后发生需求的变化,可以替换此处具体的类,而不需要更换主板,提高
AbstractMemory memory = new Memeory(); //了程序的扩展性,也做到了对修改封闭,对扩展开发。大大提高了程序的灵
AbstractSoundCard soundCard = new SoundCard(); //活性,有利于代码后期维护。这才是真正的面向对象编程。
KeyBoard keyBoard = new KeyBoard(cpu, memory, soundCard);
keyBoard.work();
}
}