面向对象设计
面向对象程序由对象组成,对象包括数据和对数据进行操作的过程(通常称为方法)。
面向对象设计最困难的部分是将系统分解成对象集合。因为要考虑许多因素:封装、粒度、依赖关系、灵活性、性能、扩展、复用等等,并且这些因素通常还是互相冲突的。那么科学地对实体进行分解,合理地设计类与类、对象与对象之间的依赖关系的是至关重要的。
1. 面向对象七大设计原则
单一职责原则:设计目单一的类;
开闭原则(OCP):对扩展开放(对提供方),对修改封闭(对使用方)。用抽象构建框架,用实现扩展细节。
当软件需要变化时,尽量通过扩展来实现,而不是通过修改原有的方法。
里氏替换原则:子类可以对父类进行扩展,但不能改变父类原有功能;
子类尽可能不重写父类的非抽象方法,继承实际是让两个类的耦合性增强了。运用里氏替换原则可以将父类设计为抽象方法或者接口,让子类继承父类或实现接口,并实现父类中的抽象方法,尽量不要重写父类的非抽象方法。
依赖倒置原则:要依赖于抽象,而不是具体的实现;针对接口编程;
依赖倒置的三种方式:构造器、接口、set方法;
接口隔离原则:使用多个专门的接口比使用单一的总接口要好;(接口的单一职责,尽量使用最小接口)
即接口的定义要尽量实现单一职责,子类不应实现自己不需要的方法。同时也要注意接口的粒度,接口不能过小,过小会导致接口泛滥,不利于代码维护。
组合重用原则:要尽量使用组合/聚合,而不是继承来达到重用的目的;
迪米特法则(最少知识法则):一个对象应当对其他对象尽可能少的了解;
2. 设计模式
(一)设计模式的基本概念
设计模式:是对软件设计中普遍存在的(反复出现)的问题,所提出的解决方案。主要关注软件系统的设计,与具体实现语言无关;
架构模式:软件设计中的高层决策(如C/S架构就属于架构模式);
惯用法:与语言相关,是最底层的模式,关注软件系统的设计与实现,实现时通过特定的编程语言来描述构件与构件之间的关系。
(二)设计模式的分类
1. 创建型模式(Creational):用于创建和管理对象类的模式;工厂模式、原型模式、单列模式、构建起模式。
抽象工厂模式:提供一个接口,可以创建一系列相关或相互依赖的对象,而无需指定它们具体的类。
构建器模式:将一个复杂类的表示与其他构造分离,使得相同的构件过程能够得出不同的表示。
单例模式:采取一定的方法保证在整个系统中某个类只能存在一个对象实例。
原型模式:利用clone()创建出对象。
2. 结构型模式(Structural):主要是为了处理类和接口的组合问题,形成更大的结构提供方案。适配器模式、桥接模式、组合模式、装饰模式、外观模式、代理模式。
组合模式:又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。
动态代理:动态代理利用反射机制,实现了目标类(被代理类)的所有接口并重写(生成字节码文件-->jvm加载字节码文件生成class类)所有方法,重写的方法体便是代理类(实现InvocationHandler接口的类)中的invoke()方法,从而达到在不改变源代码的前提下动态增强方法功能的目的。 JDK如何实现动态代理.pdf
3. 行为型模式(Behavioral):描述类或对象交互的情况,以及职责分配的问题。解释器、迭代器、中介者模式、观察者模式、访问者模式、责任链模式、策略模式等。
模板方法:将子类共行为抽取到父类中,具体不同的实现抽象为抽象方法,子类只需重写父类的抽象方法实具体业务即可。
观察者模式:目标类(被观察)只需添加一个待通知的对象的集合,在需要通知观察者时调用集合中观察者的接受方法即可。JDk中实现的观察者模式利用模板方法,将通知发送者所共有的属性(Vector)和行为(notifyObservers())封装起来。子类只需要继承 Observable类,在方法中调用notify即可。
类模式是处理类和子类之间的关系,这些关系通过继承建立,是静态的,编译时就确定下来了。
对象模式处理的是对象间的关系,这些关系在运行时是可以变化的,更具有动态性。