1 概述
在面向对象的编程中,要实现一个功能,可以有非常多的方式。在多年的经验积累总结下来,人们发现优秀的的代码总是遵循一定的范式。其中23种设计模式(Design Patterns),就是前人对优秀代码的编程范式的总结,是面向对象编程的最佳实践。合理地运用这些设计模式,已经是写出高质量,高效率,可读性强,易维护的代码的充要条件。
而设计模式的六大原则,则是设计模式都会遵守的通用法则。本文将结合简单的例子,介绍这六大原则。
2. 六大原则
2.1 依赖倒置原则(Dependency Inversion Principle)
高层模块不应该依赖于底层模块,抽象不应该依赖于细节。因为相对于实现细节的多样性与易变性,抽象类要稳定得多。
换句话说,我们应该针对接口编程。看一个反例:
public class DIViolation {
public static void main(String[] args) {
JavaDeveloper javaDeveloper = new JavaDeveloper();
PythonDeveloper pythonDeveloper = new PythonDeveloper();
Team team = new Team(javaDeveloper, pythonDeveloper);
team.teamWork();
}
}
class JavaDeveloper {
public void work() {
System.out.format("Java developer is working.");
}
}
class PythonDeveloper {
public void work() {
System.out.format("Python developer is working.");
}
}
class Team {
JavaDeveloper javaDeveloper;
PythonDeveloper pythonDeveloper;
Team(JavaDeveloper javaDeveloper, PythonDeveloper pythonDeveloper) {
this.javaDeveloper = javaDeveloper;
this.pythonDeveloper = pythonDeveloper;
}
public void teamWork() {
javaDeveloper.work();
pythonDeveloper.work();
}
}
上述例子中,类Team
和具体类JavaDeveloper
,PythonDeveloper
强耦合在了一起,扩展性极差。想象一下,某一天,PythonDeveloper
离职了,那我们得修改Team
类,把PythonDeveloper
给删除掉。又有一天,来了一位新同事CPPDeveloper
,我们又得修改Team
类,增加CPPDeveloper
。由此看出,依赖具体类的系统稳定性与扩展性是多不好。如果我们改为依赖接口呢?
public class DIObedience {
public static void main(String[] args) {
Collection<Developer> developers = new HashSet<>();
developers.add(new Javaer());
developers.add(new Pythoner());
Team team = new Team(developers);
team.teamWork();
}
}
interface Developer {
void work();
}
class Javaer implements Developer {
public void work() {
System.out.println("Java developer is working.");
}
}
class Pythoner implements Developer {
public void work() {
System.out.format("Python developer is working.");
}
}
class Team {
Collection<Developer> developers;
Team(Collection<Developer> developers) {
this.developers = developers;
}
public void teamWork() {
developers.forEa