繼承有其缺點:它只能順著單一路線演化,且會因關係緊密而難以修改。

Replace Subclass with Delegate

委託可以解決這類問題,有人因此更偏好它。
但多數情況下繼承都已能妥善解決問題,之後將其換成委託也毫無困難,作者建議「先繼承後改委託」來設計軟體。

# Before
class Renderer:
    def render(self, content):
        print(f"Rendering: {content}")

class HTMLRenderer(Renderer):
    def render(self, content):
        print(f"<html>{content}</html>")

class JSONRenderer(Renderer):
    def render(self, content):
        print(f"{{'content': '{content}'}}")

# After
class Renderer:
    def __init__(self, rendering_strategy):
        self.rendering_strategy = rendering_strategy

    def render(self, content):
        self.rendering_strategy.render(content)

class HTMLRendering:
    def render(self, content):
        print(f"<html>{content}</html>")

class JSONRendering:
    def render(self, content):
        print(f"{{'content': '{content}'}}")