一、开闭原则
设计代码结构时应应用抽象构建框架,应用实现扩展细节。对实现开放,对抽象关闭。对拓展开放,对修改关闭。
开闭原则可提高系统的可复用性和可维护性。
二、依赖倒置原则
高层模块不应依赖低层模块,二者都应依赖其抽象。坚持先顶层抽象后细节实现的设计顺序、坚持细节依赖抽象、坚持以抽象为基准搭建代码架构。
依赖倒置可减少类之间的耦合,提升系统的稳定性。
不合适的设计:
public class ShapePainter {
public void drawSquare(){
System.out.println("正方形");
}
public void drawCircle(){
System.out.println("圆形");
}
}
调用:
public static void main(String[] args) {
ShapePainter shapePainter = new ShapePainter ();
shapePainter .drawSquare();
shapePainter .drawCircle();
}
使用依赖倒置原则:
public interface Ishape() {
void draw();
}
public class Squre() implements Ishape {
@Override
public void draw() {
System.out.println("正方形");
}
}
public class Circle() implements Ishape {
@Override
public void draw() {
System.out.println("圆形");
}
}
public class ShapePainter {
public void draw(Ishape shape) {
shape.draw();
}
}
调用:
public static void main(String[] args){
ShapePainter shapePainter = new ShapePainter ();
shapePainter .draw(new Square());
shapePainter .draw(new Circle());
}
用代码形式表达个意思,可能有误,不必较真。
我们可以看到,不合适的设计中,高层模块ShapePainter依赖于低层模块(各种形状),我们想要使其都依赖与抽象,就必须建立一个中间抽象对象,自然可以想到把形状抽象出去,抽象成Ishape,通过实现成为各种形状的依赖,通过依赖注入成为ShapePainter 依赖,从而使得高低层模块都依赖于改抽象接口。在遵循依赖倒置原则设计代码结构之后,当ShapePainter 想画一些新的形状(扩展细节)时,只需要扩展Ishape 的实现即可,无需改动原有底层代码;而若在ShapePainter 里边直接写具体的draw细节,会导致在需要新增形状时,需要对底层ShapePainter 类进行改动,draw方法的调用类与ShapePainter 类耦合性强,并且随着业务的不断拓展需要不断地修改。
三、单一职责原则
一个类、接口或方法只负责一项职责,避免存在多于一个导致类变更的原因。
四、接口隔离原则
接口隔离原则要求使用多个专门的接口代替单一的总接口,调用方不需要依赖其不需要的接口。
例如:
public interface IAnimal{
void run();
void fly();
void swim();
}
public class Fish implements IAnimal{
@Override
void run(){。。。};
@Override
void fly(){。。。};
@Override
void swim(){。。。};
}
public class Dog implements IAnimal{
。。。
}
Fish的run()方法,Dog的fly方法是没用的,但必须override空着。
这种情况可以将IAnimal接口继续细分,
public interface IRunAnimal{
void run();
}
public interface ISwimAnimal{
void swim();
}
public interface IFlyAnimal{
void fly();
}
这样,Dog、Fish各取所需,实现其需要的接口即可。
单一职责原则可提高系统的可维护性,防止代码臃肿,职责分离、降低变更风险。
五、迪米特原则
又称最少知道原则,该原则指导设计人在设计代码时,尽可能地让类只与朋友类交流(朋友类:出现在成员变量、方法输入/输出参数中的类都算朋友类,出现在方法体中的类不属于朋友类。)能很好地减少类与类之间的耦合。该原则能让一个对象对另一个对象保持最少的了解。
例:我向朋友打听一些事情,朋友也不知道但他知道他的朋友知道,于是他需要先去问他的朋友再来告诉我。
六、里氏替换原则
简单地讲,就是允许将程序中所有父类对象都替换成子类对象,程序依旧能正常运行。
这要求子类可以扩展父类的功能,但不能改变父类原有的功能:
1、子类不能覆盖父类的非抽象方法。
2、子类可以增加自己特有的方法。
3、当子类重载父类方法时,方法的输入应该比分类方法更宽松、输出要比父类更严格。
七、合成复用原则
减少继承、尽可能地使用对象组合/聚合来实现软件复用。
继承是白箱复用,这会将所有实现细节都暴露给子类。组合/聚合是黑箱复用,子类无法获取自身之外的对象实现细节的