设计模式的出现,体现了先进的OO设计原则,这些设计原则以及设计模式的初衷都是为了拯救陷于系统维护噩梦的程序员:越来越大量的不断增加的复杂业务逻辑使得系统设计者们在OO设计中,仅仅单靠java原本的封装、抽象、继承和多态已经将他们自己置入两难的境地。一方面,OO程序设计者要求较好的代码复用性,于是将自己手头仅有的为数不多的几样工具之一——继承大肆滥用,于是将代码中间的类推向了一个固化、强耦合的不归路。另一方面,现代系统要求迭代更新快,对系统开发完成后的可扩展性,可维护性提出了越来越高的要求,于是继承带来的强耦合以及子类之间的差异性带来的大量针对型修改成为了程序员的噩梦。
具体来说,一般意义上来讲,为大家所承认的具有面向对象色彩的程序复用方法即是继承和实现接口,但严格来讲,实现接口并没有实现程序的复用:一、接口只定义了方法名,而未定义方法体。在具体实现某接口时,要在具体实现类中实现其方法体。在代码维护阶段,我们针对方法的某种具体实现进行修改仍需到接口方法的对应具体实现类中去修改,这并没有降低程序员的工作量。二、实现类实现某一个接口时需要将该接口的方法全部实现,使原本该实现类不需要的方法,被迫存在,这不但没有提高代码的复用性,还使实现类的方法泛滥,变相的降低了代码复用的优势,增加了程序员的工作量。而对于继承,它虽然很好地执行了代码的复用性,但也一定程度上存在着实现接口所具有的问题。不过,“继承”的问题还远不止于此:由于很多子类共享的方法已经在父类中实现,因此,当后续的业务需求需要使一些子类对父类中的这些共享方法提出差异性要求时,这些子类就只能对这些共享方法进行覆盖,父类某种意义上就沦为了接口,损害了其复用性。而如果要是直接修改父类中的方法而没有考虑全面子类中的情况,严重的后果就发生了,代码依然能够运行,目标子类也得到了正确的结果,但是,其他子类却发生了严重的问题,这就是继承带来的各个子类通过父类强耦合在了一起。
要想解除代码强耦合,同时提高代码的复用性,设计模式是一个好的选择,基本设计模式种类仍然是当初四人组在他们著名的《设计模式》一书中定义的23中设计模式分别为:Strategy Observer Decorator Abstract Factory Factory Method Singleton Command Adapter Facade Template Method Iterator Composite State Proxy Bridge Builder Chain of Responsibility Flyweight Interpreter Mediator Memento Prototype Visitor 。
建立正确的OO程序设计观:
一、将纷繁复杂的各式代码封装成类,并于现实中的对象建立思维领域的映射,为了是封装的类与现实中的对象更加贴切,要尽量从具体向抽象过度;
二、每当编写一个类时,就要当作是在刻画一个对象,一切该对象所蕴含的代码都要从该对象角度出发,即:把自己想象成这个对象,将其他对象想象成与自己平等的对象
三、由于其他对象与OO设计者所代表的对象是平等,所以,其他对象的属性对于OO设计者是透明的。
事实上,设计模式都是基于OO设计原则,经过大量的OO设计者的大量的设计实践总结而来的,其中,OO设计原则是设计模式的精髓所在,这些设计原则包括很多,在这里列举几条:
一、封装变化。按照一定长时间的对未来的预期,将对象中的变化部分与不变部分分开,不可变部分仍封装在该对象中,可变部分单独封装 。
二、多用组合,少用继承。将对象行为尽可能的以委托给其他的对象的形式注入进来,这样增加了灵活性和可扩展性。
三、针对接口编程、不针对实现编程。我们在编写代码过程中尽量考虑实例所实现的接口能做什么,而不要局限在该实例可以做什么。
四、为交互对象之间的松耦合设计而努力。
五、类应该对扩展开放,对修改关闭。顾名思义,类应该是可扩展的,既不改变原来已有方法的条件下,使类增加新的能力,而不是以改变已有方法为代价来增加新的能力。
六、依赖抽象,不依赖具体实现。类间依赖关系中,所依赖的类为抽象类,最好是接口,而不依赖于具体的实现类,这样对松耦合有着重要的意义。
七、剥夺对象的主动权,对象只需履行被动权。在OO编程中为了松耦合,尽量使对象之间免于纠缠在一起,要减少让对象主动获得信息,而应该命令对象完成某个动作之后交还行动权,等待下一步动作的命令。
掌握OO设计原则的基础上,还要运用设计模式积累大量经验,但是要免于陷入处处谈模式的极端。