设计模式之开放封闭原则
[Ivar Jacobson]: All systems change during their life cycles. This must be borne in mind when developing systems expected to last longer than the first version.
[Bertrand Meyer]:Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.
软件实体(类、模块、函数等),应对扩展开放,但对修改封闭
开放封闭原则(Open Close Principle-OCP)(面向扩展开放,面向修改封闭)
面向扩展开放:也就是说模块的行为是能够被扩展的。当应用程序的需求变化时,可以使模块表现出全新的或与以往不同的行为,以满足新的需求。
面向修改封闭:模块的源代码是不能被侵犯的,任何人都不允许修改已有源代码。除非是改bug。
人话:
扩展新功能比较方便,不需要修改原有代码
优化旧功能,改动也应该在很小的范围内,不应该影响暴露出去的代码
OCP是面向对象的核心,是所有原则的目标,关键在于抽象。
单一职责原则:类要职责单一;里氏替换原则:不要破坏继承体系;依赖倒置原则:面向接口编程;接口隔离原则:设计接口的要精简单一;迪米特法则:降低耦合。开闭原则是总纲,要对扩展开放,对修改关闭。
Talk is cheap, show me the code.
举一个计算多个图形周长之和的例子:
// 对修改不封闭,对扩展也不开放 public static double edgeLengthSum(List<Object> objects) { if (objects == null || objects.isEmpty()) { return -1; } double sum = 0; for (Object shape : objects) { if (shape == null) { continue; } if (shape instanceof Rectangle) { sum += (((Rectangle) shape).getHeight() + ((Rectangle) shape).getWidth()) * 2; } else if (shape instanceof Circle) { sum += 2 * Math.PI * ((Circle) shape).getRadius(); } // else if (shape instanceof Triangle) { // sum += ((Triangle) shape).getSideLen() * 3; // } } return sum; }
修改后:
// 抽象是关键
abstract static class Shape { public abstract double edgeLength(); } // 对修改封闭,对扩展也开放 public static double edgeLengthSum(List<Shape> shapes) { if (shapes == null || shapes.isEmpty()) { return -1; } double sum = 0; for (Shape shape : shapes) { if (shape == null) { continue; } sum += shape.edgeLength(); } return sum; }