开放/闭合原则 (OCP) 指出软件实体应该对扩展开放,对修改关闭:您应该通过添加新代码来添加新行为,而不是通过编辑现有的、经过测试的代码。
OCP 所针对的代码味道
python
():
shape.kind == : * shape.r **
shape.kind == : shape.s **
shape.kind == : shape.w * shape.h
每个新类型都会强制对不断增长的 if/elif 链进行修改——脆弱且容易滋生错误。
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self): ...
class Circle(Shape):
def __init__(self, r): self.r = r
def area(self): return 3.14159 * self.r ** 2
class Triangle(Shape): # NEW behavior = NEW class
def __init__(self, b, h): self.b, self.h = b, h
def area(self): return 0.5 * self.b * self.h
def total_area(shapes): # never changes again
return sum(s.area() for s in shapes)
添加 Triangle 需要对 total_area 零修改——无需修改的扩展。
→ polymorphism / inheritance → strategy pattern (inject behavior)
→ plugins / interfaces → higher-order functions / callbacks
投机性地实现 OCP 会导致过度工程化——为可能永远不会出现的变化构建抽象。在变化可能发生的地方应用它("三法则":在变化实际出现后进行抽象)。
编辑经过充分测试的代码以添加功能会在该代码已支持的所有内容中引入回归风险;OCP 将新行为限制在新的、隔离的单元中。
这是可扩展框架和插件系统背后的原则——它依赖于 LSP,因为可替换的子类型是使"闭合"核心保持安全不被修改的原因。