(1)针对接口编程,而不是针对实现编程
(2)优先使用对象组合,而少用继承
(3)封装变化点
具体的设计原则:
(1)单一职责原则
(2)开放封闭原则
(3)Liskov替换原则
(4)依赖倒置原则
(5)接口隔离原则
比模式更重要的原则(GRASP职责分配原则)
1:信息专家[方法分配](如果某个类具有某个职责需要的所有信息那么该方法应分配给该类)
2:创造者[对象创建](如果A是B的聚合,容器或A持有B的信息或A纪录了B的实例或A频繁使用B则A应创建B)
3:低耦合[方法分配](1无通信的对象之间不要建立无为的连接2A与B之间有连接若分配A的职责给B不合适则应把B的职责分配给A)
4:高内聚[方法分配](功能性紧密相关的职责应放在一个类里完成有限的功能)
5:控制器["类间关系"](应把接收和处理系统事件的职责分配给一个能代表整个系统的类)
6:多态[可扩展]
7:纯虚构[封装变化]
8:间接[隔离对象]
9:保护变化[封装不变化]
-------------------------
什么是开放封闭原则
在面向对象领域,有一个很著名的原则:OCP(Open-Closed Principle),它的核心含意是:一个好的设计应该能够容纳新的功能需求的增加,但是增加的方式不是通过修改又有的模块(类),而是通过增加新的模块(类)来完成的。如果一个设计能够遵循OCP,那么就能够有效的避免上述的问题。 要是一个设计能够符合OCP原则,就要求我们在进行设计时不能简单的以功能为核心。要实现OCP的关键是抽象,抽象表征了一个固定的行为,但是对于这个行为可以有很多个不同的具体实现方法。通过抽象,我们就可以用一个固定的抽象的概念来代替哪些容易变化的数量众多的具体的概念,并且使得原来依赖于哪些容易变化的概念的模块,依赖于这个固定的抽象的概念,这样的结果就是:系统新的需求的增加,仅仅会引起具体的概念的增加,而不会影响依赖于具体概念的抽象体的其他模块。在实现的层面上,抽象体是通过抽象类来描述的,在Java中是接口(interface)。 (OCP原则背后的主要机制是抽象和多态。支持抽象和多态的关键机制是继承。)
---------------------------
什么是Liskov替换原则若对于每一个类型P的对象p1,都存在一个类型C的对象c1,使得在所有针对C编写的程序P中,用p1替换c1后,程序P的行为功能不变,则C是P的子类型。 LSP原则清楚地指出,OOD中IS-A关系是就行为功能而言。行为功能(behavior)不是内在的、私有的,而是外在、公开的,是客户程序所依赖的。行为功能(behavior)才是软件所关注的问题!所有派生类的行为功能必须和客户程序对其基类所期望的保持一致。例如如下设计:
public class Rectangle
{
private long width;
private long height;
public void setWidth(long width){
this.width=width;
}
public void setHeight(long height){
this.height=height;
}
public long getWidth(){
return width;
}
public long getHeight(){
return height;
}
public void resizeWidth(){
width++;
}
};
public class Square : Rectangle
{
public void setWidth(long width){
this.width=width;
this.height=width;
}
public void setHeight(long height){
this.width=width;
this.height=width;
}
public void resizeWidth(){
width++;
height++;
}
};
并不是一个合理的设计,Square继承了Rectangle的接口,但是从Square本身来看,setWidth,setLength接口的设立并不合理,导致代码所表达的意义与基类的不同。 DBC(Design by Contract)定义把类和其客户之间的关系看作是一个正式的协议,明确各方的权利和义务。DBC对类的要求类的方法声明为先决条件(precondition)和后续条件(postcondition)。为了让方法得以执行,先决条件必须为真。完成后,方法保证后续条件为真。DBC对派生类的要求当重新定义派生类中的例行程序时,我们只能用更弱的先决条件和更强的后续条件替换之。 LSP原则是符合OCP原则应用程序的一项重要特性。仅当派生类能完全替换基类时,我们才能放心地重用那些使用基类的函数和修改派生类型。 {
private long width;
private long height;
public void setWidth(long width){
this.width=width;
}
public void setHeight(long height){
this.height=height;
}
public long getWidth(){
return width;
}
public long getHeight(){
return height;
}
public void resizeWidth(){
width++;
}
};
public class Square : Rectangle
{
public void setWidth(long width){
this.width=width;
this.height=width;
}
public void setHeight(long height){
this.width=width;
this.height=width;
}
public void resizeWidth(){
width++;
height++;
}
};
--------------------------
什么是依赖倒转原则(DIP)
高层模块不应该依赖于低层模块。二者都应该依赖于抽象。抽象不应该依赖于细节。细节应该依赖于抽象。
实施重点:从问题的具体细节中分离出抽象,以抽象方式对类进行耦合。
不足:导致生成大量的类。假定所有的具体类都是会变化的,这也不总是正确的。
--------------------------
什么是接口隔离原则(ISP)
一个没有经验的设计师往往想节省接口的数目,将一些功能相近或功能相关的接口合并,并将这看成是代码优化的一部分。
定义:从一个客户类的角度来讲:一个类对另外一个类的依赖性应当是建立在最小的接口上的。使用多个专门的接口比使用单一的总接口要好。
-------------------------
什么是合成/聚合复用原则(CARP)
尽量使用合成/聚合、尽量不使用继承
定义:在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分;新的对象通过向这些对象的委派达到复用这些对象的目的
-------------------------
以上是我搜集整理的,希望对大家有用.
-------------------------
什么是合成/聚合复用原则(CARP)
尽量使用合成/聚合、尽量不使用继承
定义:在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分;新的对象通过向这些对象的委派达到复用这些对象的目的
-------------------------
以上是我搜集整理的,希望对大家有用.