当前位置: 首页 > article >正文

【设计模式】6大设计原则和23种设计模式

  • 设计原则 是更高层次的思想指导,强调代码的可维护性、稳定性和灵活性。
  • 设计模式 是实现设计原则的具体方法和工具,解决特定场景的问题。

I、6大设计原则

  1. 单一职责原则(SRP, Single Responsibility Principle)

    • 每个类应该只有一个引起变化的原因,职责应该保持单一。
    • 目标:高内聚,低耦合。
  2. 开闭原则(OCP, Open/Closed Principle)

    • 软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。
    • 目标:通过扩展实现变化,而非直接修改代码。
  3. 里氏替换原则(LSP, Liskov Substitution Principle)

    • 子类必须能够替代其父类而不改变程序的正确性。
    • 目标:保证继承的正确性。
  4. 依赖倒置原则(DIP, Dependency Inversion Principle)

    • 高层模块不依赖于低层模块,二者都应该依赖于抽象(接口/抽象类)。
    • 目标:面向接口编程,解耦高层与底层。
  5. 接口隔离原则(ISP, Interface Segregation Principle)

    • 一个类不应该强制依赖不需要的接口,接口应该小而专一。
    • 目标:避免对一个类造成无关的强耦合。

以上5种原则常被称为SOLID 原则

  1. 迪米特法则(LoD, Law of Demeter,又称最少知道原则)
    • 一个对象应该尽量少地了解其他对象,应通过中介转交信息而非直接依赖。
    • 目标:降低对象之间的耦合性。

II、23种设计模式

一、创建型模式(Creational Patterns)

创建型模式的关注点是对象的创建。它们通过对对象创建过程的抽象,减少代码中的耦合性,使创建对象的过程更灵活和可控。
它们解决的问题通常是:如何以更优雅、灵活的方式创建对象,同时避免直接使用new关键字的硬编码。

  1. 单例模式(Singleton Pattern)
    单例模式确保一个类只有一个实例,并提供全局访问点。
    示例代码
class Singleton:
    _instance = None

    def __new__(cls, *args, **kwargs):
        if not cls._instance:  # 如果实例不存在,创建一个实例
            cls._instance = super().__new__(cls, *args, **kwargs)
        return cls._instance

# 测试单例模式
singleton1 = Singleton()
singleton2 = Singleton()

print(singleton1 is singleton2)  # 输出: True (两个变量引用同一个实例)
  1. 工厂方法模式(Factory Method Pattern)
    定义一个创建对象的接口,但由子类决定实例化的具体类。
    示例代码
from abc import ABC, abstractmethod

# 抽象产品
class Animal(ABC):
    @abstractmethod
    def make_sound(self):
        pass

# 具体产品
class Dog(Animal):
    def make_sound(self):
        return "Woof!"

class Cat(Animal):
    def make_sound(self):
        return "Meow!"

# 工厂类
class AnimalFactory:
    @staticmethod
    def get_animal(animal_type):
        if animal_type == "dog":
            return Dog()
        elif animal_type == "cat":
            return Cat()
        else:
            raise ValueError("Unknown animal type")

# 测试
animal = AnimalFactory.get_animal("dog")
print(animal.make_sound())  # 输出: "Woof!"
  1. 抽象工厂模式(Abstract Factory Pattern)
    提供一个接口,用于创建相关或依赖对象的集合,而不需要指定它们的具体类。
    示例代码
from abc import ABC, abstractmethod

# 抽象产品
class Chair(ABC):
    @abstractmethod
    def sit_on(self):
        pass

class Sofa(ABC):
    @abstractmethod
    def lie_on(self):
        pass

# 具体产品
class ModernChair(Chair):
    def sit_on(self):
        return "Sitting on a modern chair"

class ModernSofa(Sofa):
    def lie_on(self):
        return "Lying on a modern sofa"

class VictorianChair(Chair):
    def sit_on(self):
        return "Sitting on a Victorian chair"

class VictorianSofa(Sofa):
    def lie_on(self):
        return "Lying on a Victorian sofa"

# 抽象工厂
class FurnitureFactory(ABC):
    @abstractmethod
    def create_chair(self):
        pass

    @abstractmethod
    def create_sofa(self):
        pass

# 具体工厂
class ModernFurnitureFactory(FurnitureFactory):
    def create_chair(self):
        return ModernChair()

    def create_sofa(self):
        return ModernSofa()

class VictorianFurnitureFactory(FurnitureFactory):
    def create_chair(self):
        return VictorianChair()

    def create_sofa(self):
        return VictorianSofa()

# 测试
def furniture_client(factory):
    chair = factory.create_chair()
    sofa = factory.create_sofa()
    print(chair.sit_on())
    print(sofa.lie_on())

modern_factory = ModernFurnitureFactory()
victorian_factory = VictorianFurnitureFactory()

print("Modern Furniture:")
furniture_client(modern_factory)

print("\nVictorian Furniture:")
furniture_client(victorian_factory)
  1. 建造者模式(Builder Pattern)
    将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。
    示例代码
# 产品
class House:
    def __init__(self):
        self.walls = None
        self.doors = None
        self.windows = None

    def __str__(self):
        return f"House with {self.walls}, {self.doors}, and {self.windows}"

# 抽象建造者
class HouseBuilder:
    def build_walls(self):
        pass

    def build_doors(self):
        pass

    def build_windows(self):
        pass

    def get_result(self):
        pass

# 具体建造者
class SimpleHouseBuilder(HouseBuilder):
    def __init__(self):
        self.house = House()

    def build_walls(self):
        self.house.walls = "basic walls"

    def build_doors(self):
        self.house.doors = "simple doors"

    def build_windows(self):
        self.house.windows = "plain windows"

    def get_result(self):
        return self.house

# 指挥者
class Director:
    def __init__(self, builder):
        self.builder = builder

    def construct(self):
        self.builder.build_walls()
        self.builder.build_doors()
        self.builder.build_windows()

# 测试
builder = SimpleHouseBuilder()
director = Director(builder)
director.construct()

house = builder.get_result()
print(house)  # 输出: House with basic walls, simple doors, and plain windows
  1. 原型模式(Prototype Pattern)
    通过复制现有对象来创建新的对象(浅拷贝或深拷贝),而不是通过实例化对象。
    示例代码
import copy

class Prototype:
    def __init__(self):
        self._objects = {}

    def register(self, key, obj):
        self._objects[key] = obj

    def clone(self, key, **attrs):
        if key not in self._objects:
            raise ValueError("Prototype not found")
        obj = copy.deepcopy(self._objects[key])
        obj.__dict__.update(attrs)
        return obj

# 测试
class Car:
    def __init__(self, name, color):
        self.name = name
        self.color = color

    def __str__(self):
        return f"{self.name} ({self.color})"

# 原型管理器
car_prototype = Prototype()
car_prototype.register("basic_car", Car("Generic Car", "white"))

# 克隆对象并修改属性
car1 = car_prototype.clone("basic_car", name="Tesla Model S", color="red")
car2 = car_prototype.clone("basic_car", name="BMW 3 Series", color="blue")

print(car1)  # 输出: Tesla Model S (red)
print(car2)  # 输出: BMW 3 Series (blue)

二、 结构型模式(Structural Patterns)

结构型模式的关注点是程序的对象结构。它们处理的是如何优雅地组织类和对象之间的关系,以形成更大的、灵活的结构。
它们解决的问题是:如何组合类和对象来构建更复杂的、系统化的结构,同时保持系统的可扩展性和模块化。

  1. 适配器模式(Adapter Pattern)
    将一个类的接口转换为客户端期望的另一种接口,使原本接口不兼容的类可以一起工作。
    示例代码
# 不兼容的类
class OldPrinter:
    def print_text(self):
        return "This is an old printer."

# 新接口期望的方法
class NewInterface:
    def print(self):
        pass

# 适配器
class PrinterAdapter(NewInterface):
    def __init__(self, old_printer):
        self.old_printer = old_printer

    def print(self):
        return self.old_printer.print_text()

# 测试
old_printer = OldPrinter()
adapter = PrinterAdapter(old_printer)
print(adapter.print())  # 输出: This is an old printer.
  1. 桥接模式(Bridge Pattern)
    将抽象部分与它的实现部分分离,使它们都可以独立变化。
    示例代码
# 实现部分
class DrawingAPI:
    def draw_circle(self, x, y, radius):
        pass

class DrawingAPI1(DrawingAPI):
    def draw_circle(self, x, y, radius):
        print(f"API1.circle at ({x}, {y}) with radius {radius}")

class DrawingAPI2(DrawingAPI):
    def draw_circle(self, x, y, radius):
        print(f"API2.circle at ({x}, {y}) with radius {radius}")

# 抽象部分
class Shape:
    def __init__(self, drawing_api):
        self.drawing_api = drawing_api

    def draw(self):
        pass

class Circle(Shape):
    def __init__(self, x, y, radius, drawing_api):
        super().__init__(drawing_api)
        self.x = x
        self.y = y
        self.radius = radius

    def draw(self):
        self.drawing_api.draw_circle(self.x, self.y, self.radius)

# 测试
circle1 = Circle(1, 2, 3, DrawingAPI1())
circle1.draw()  # 输出: API1.circle at (1, 2) with radius 3

circle2 = Circle(5, 7, 9, DrawingAPI2())
circle2.draw()  # 输出: API2.circle at (5, 7) with radius 9
  1. 组合模式(Composite Pattern)
    将对象组合成树形结构,以表示 “整体 - 部分” 的层次结构,并使客户端对单个对象和组合对象的使用具有一致性。
    示例代码
class Component:
    def show(self):
        pass

class Leaf(Component):
    def __init__(self, name):
        self.name = name

    def show(self):
        print(f"Leaf: {self.name}")

class Composite(Component):
    def __init__(self, name):
        self.name = name
        self.children = []

    def add(self, component):
        self.children.append(component)

    def show(self):
        print(f"Composite: {self.name}")
        for child in self.children:
            child.show()

# 测试
root = Composite("Root")
root.add(Leaf("Leaf A"))
root.add(Leaf("Leaf B"))

branch = Composite("Branch X")
branch.add(Leaf("Leaf XA"))
branch.add(Leaf("Leaf XB"))

root.add(branch)
root.show()
  1. 装饰器模式(Decorator Pattern)
    动态地给一个对象添加一些额外的职责,而不会影响其他对象的功能。
    示例代码
# 基础组件
class Coffee:
    def cost(self):
        return 5  # 基础价格

    def description(self):
        return "Coffee"

# 装饰器基类
class CoffeeDecorator(Coffee):
    def __init__(self, coffee):
        self._coffee = coffee

    def cost(self):
        return self._coffee.cost()

    def description(self):
        return self._coffee.description()

# 具体装饰器
class Milk(CoffeeDecorator):
    def cost(self):
        return self._coffee.cost() + 2

    def description(self):
        return self._coffee.description() + " + Milk"

class Sugar(CoffeeDecorator):
    def cost(self):
        return self._coffee.cost() + 1

    def description(self):
        return self._coffee.description() + " + Sugar"

# 测试
coffee = Coffee()
print(coffee.description(), "costs:", coffee.cost())  # Coffee costs: 5

coffee = Milk(coffee)
print(coffee.description(), "costs:", coffee.cost())  # Coffee + Milk costs: 7

coffee = Sugar(coffee)
print(coffee.description(), "costs:", coffee.cost())  # Coffee + Milk + Sugar costs: 8
  1. 外观模式(Facade Pattern)
    为子系统中的一组接口提供一个统一的高层接口,使得子系统更易于使用。
    示例代码
class CPU:
    def start(self):
        print("CPU started.")

    def stop(self):
        print("CPU stopped.")

class Memory:
    def load(self):
        print("Memory loaded.")

    def clear(self):
        print("Memory cleared.")

class HardDrive:
    def read(self):
        print("HardDrive reading data.")

    def write(self):
        print("HardDrive writing data.")

# 外观类
class ComputerFacade:
    def __init__(self):
        self.cpu = CPU()
        self.memory = Memory()
        self.hard_drive = HardDrive()

    def start_computer(self):
        self.cpu.start()
        self.memory.load()
        self.hard_drive.read()

    def shutdown_computer(self):
        self.hard_drive.write()
        self.memory.clear()
        self.cpu.stop()

# 测试
computer = ComputerFacade()
computer.start_computer()
computer.shutdown_computer()
  1. 享元模式(Flyweight Pattern)
    通过共享技术实现大量细粒度对象的高效利用,减少内存占用。
    示例代码
class Flyweight:
    def __init__(self, shared_state):
        self.shared_state = shared_state

    def operation(self, unique_state):
        print(f"Shared: {self.shared_state}, Unique: {unique_state}")

class FlyweightFactory:
    def __init__(self):
        self.flyweights = {}

    def get_flyweight(self, key):
        if key not in self.flyweights:
            self.flyweights[key] = Flyweight(key)
        return self.flyweights[key]

# 测试
factory = FlyweightFactory()

flyweight1 = factory.get_flyweight("State A")
flyweight2 = factory.get_flyweight("State A")

flyweight1.operation("Unique 1")
flyweight2.operation("Unique 2")

print(flyweight1 is flyweight2)  # 输出: True (共享的对象)
  1. 代理模式(Proxy Pattern)
    为其他对象提供一个代理,以控制对该对象的访问。
    示例代码
class RealSubject:
    def request(self):
        print("RealSubject handling the request.")

class Proxy:
    def __init__(self, real_subject):
        self.real_subject = real_subject

    def request(self):
        print("Proxy delegating request to RealSubject.")
        self.real_subject.request()

# 测试
real_subject = RealSubject()
proxy = Proxy(real_subject)
proxy.request()

三、行为型模式(Behavioral Patterns)

行为型模式的关注点是对象之间的交互和职责分配。它们描述的是对象如何协作以完成任务,以及职责如何分配到不同的类之中。
它们解决的问题是:在运行时,让对象之间的通信变得灵活、解耦,并使代码具有更清晰的逻辑。

  1. 责任链模式(Chain of Responsibility Pattern)
    将多个对象以链式结构组织起来,使得这些对象依次处理一个请求,直到有对象处理成功为止。
    示例代码
from abc import ABC, abstractmethod

class Handler(ABC):
    def __init__(self, successor=None):
        self._successor = successor

    @abstractmethod
    def handle(self, request):
        pass

class ConcreteHandlerA(Handler):
    def handle(self, request):
        if request == "A":
            print("Handler A handled the request")
        elif self._successor:
            self._successor.handle(request)

class ConcreteHandlerB(Handler):
    def handle(self, request):
        if request == "B":
            print("Handler B handled the request")
        elif self._successor:
            self._successor.handle(request)

# 测试
handler_chain = ConcreteHandlerA(ConcreteHandlerB())
handler_chain.handle("A")  # Handler A handled the request
handler_chain.handle("B")  # Handler B handled the request
handler_chain.handle("C")  # 未处理
  1. 命令模式(Command Pattern)
    将请求封装为一个对象,从而使用户可以用不同的请求对客户端进行参数化,以及对请求排队或记录请求日志。
    示例代码
from abc import ABC, abstractmethod

# 命令接口
class Command(ABC):
    @abstractmethod
    def execute(self):
        pass

# 具体命令
class PrintCommand(Command):
    def __init__(self, receiver, message):
        self.receiver = receiver
        self.message = message

    def execute(self):
        self.receiver.action(self.message)

# 接收者
class Receiver:
    def action(self, message):
        print(f"Executing action: {message}")

# 调用者
class Invoker:
    def __init__(self):
        self._commands = []

    def add_command(self, command):
        self._commands.append(command)

    def execute_commands(self):
        for command in self._commands:
            command.execute()

# 测试
receiver = Receiver()
command1 = PrintCommand(receiver, "Command 1")
command2 = PrintCommand(receiver, "Command 2")
invoker = Invoker()

invoker.add_command(command1)
invoker.add_command(command2)
invoker.execute_commands()
  1. 解释器模式(Interpreter Pattern)
    提供一种解释语言的语法或表达式的方式,并实现解释器来处理这些语言规则。
    示例代码
from abc import ABC, abstractmethod

# 抽象表达式类
class Expression(ABC):
    @abstractmethod
    def interpret(self) -> int:
        pass

# 数字表达式(终结符表达式)
class Number(Expression):
    def __init__(self, value: int):
        self.value = value

    def interpret(self) -> int:
        return self.value

# 加法表达式
class Add(Expression):
    def __init__(self, left: Expression, right: Expression):
        self.left = left
        self.right = right

    def interpret(self) -> int:
        return self.left.interpret() + self.right.interpret()

# 减法表达式
class Subtract(Expression):
    def __init__(self, left: Expression, right: Expression):
        self.left = left
        self.right = right

    def interpret(self) -> int:
        return self.left.interpret() - self.right.interpret()

# 解析器
class Parser:
    @staticmethod
    def parse(expression: str) -> Expression:
        tokens = expression.split()
        result = Number(int(tokens[0]))  # 初始化第一个数字

        i = 1
        while i < len(tokens):
            operator = tokens[i]
            next_number = Number(int(tokens[i + 1]))
            
            if operator == "+":
                result = Add(result, next_number)
            elif operator == "-":
                result = Subtract(result, next_number)

            i += 2  # 跳过操作符和数字
        return result

# 使用解释器模式
if __name__ == "__main__":
    expression = "3 + 5 - 2"
    parsed_expression = Parser.parse(expression)
    result = parsed_expression.interpret()
    print(f"Result of '{expression}' is: {result}") # 输出:Result of '3 + 5 - 2' is: 6
  1. 迭代器模式(Iterator Pattern)
    提供一种方法,使对象集合可以顺序访问其中的元素,而无须暴露集合内部表示方式。
    示例代码
class Iterator:
    def __init__(self, data):
        self._data = data
        self._index = 0

    def has_next(self):
        return self._index < len(self._data)

    def next(self):
        if not self.has_next():
            raise StopIteration
        value = self._data[self._index]
        self._index += 1
        return value

# 测试
data = [1, 2, 3]
iterator = Iterator(data)
while iterator.has_next():
    print(iterator.next())
  1. 中介者模式(Mediator Pattern)
    用一个中介对象来封装一组对象之间的交互,使这些对象之间不需要显式相互引用,从而实现松散耦合。
    示例代码
class Mediator:
    def notify(self, sender, event):
        pass

class ConcreteMediator(Mediator):
    def __init__(self):
        self.colleague1 = Colleague1(self)
        self.colleague2 = Colleague2(self)

    def notify(self, sender, event):
        if event == "event1":
            print("Mediator reacts to event1 and triggers Colleague2")
            self.colleague2.do_action()
        elif event == "event2":
            print("Mediator reacts to event2 and triggers Colleague1")
            self.colleague1.do_action()

class Colleague:
    def __init__(self, mediator):
        self.mediator = mediator

class Colleague1(Colleague):
    def do_action(self):
        print("Colleague1 does action")

class Colleague2(Colleague):
    def do_action(self):
        print("Colleague2 does action")

# 测试
mediator = ConcreteMediator()
mediator.colleague1.mediator.notify(mediator.colleague1, "event1")
  1. 备忘录模式(Memento Pattern)
    保存对象的某个状态,以便在适当的时候恢复。
    示例代码
# 备忘录类,存储对象的状态
class Memento:
    def __init__(self, state):
        self._state = state

    def get_state(self):
        return self._state


# 原始类,负责创建和恢复备忘录
class TextEditor:
    def __init__(self):
        self._text = ""

    def type(self, words):
        self._text += words

    def get_text(self):
        return self._text

    # 创建备忘录
    def save(self):
        return Memento(self._text)

    # 恢复状态
    def restore(self, memento):
        self._text = memento.get_state()


# 管理者类,负责保存所有备忘录
class Caretaker:
    def __init__(self):
        self._history = []

    # 添加备忘录到历史记录
    def save(self, memento):
        self._history.append(memento)

    # 从历史记录中获取备忘录
    def undo(self):
        if not self._history:
            return None
        return self._history.pop()


# 客户端代码
if __name__ == "__main__":
    editor = TextEditor()
    caretaker = Caretaker()

    # 用户输入文字
    editor.type("Hello, ")
    caretaker.save(editor.save())  # 保存当前状态

    editor.type("world!")
    caretaker.save(editor.save())  # 保存当前状态

    editor.type(" This is a demo of Memento Pattern.")
    print("当前文本:", editor.get_text())

    # 撤销到上一个状态
    editor.restore(caretaker.undo())
    print("撤销后:", editor.get_text())

    # 再次撤销
    editor.restore(caretaker.undo())
    print("再次撤销后:", editor.get_text())
  1. 观察者模式(Observer Pattern)
    定义对象间的一对多依赖,当被观察的对象状态改变时,所有观察者对象都会收到通知。
    示例代码
# 主题类
class Subject:
    def __init__(self):
        self._observers = []

    def attach(self, observer):
        self._observers.append(observer)

    def detach(self, observer):
        self._observers.remove(observer)

    def notify(self):
        for observer in self._observers:
            observer.update()

# 观察者接口
class Observer:
    def update(self):
        pass

# 具体观察者
class ConcreteObserverA(Observer):
    def update(self):
        print("Observer A: Received update!")

class ConcreteObserverB(Observer):
    def update(self):
        print("Observer B: Received update!")

# 测试
subject = Subject()
observer_a = ConcreteObserverA()
observer_b = ConcreteObserverB()

subject.attach(observer_a)
subject.attach(observer_b)

subject.notify()
  1. 状态模式(State Pattern)
    允许对象在其内部状态改变时改变其行为。
    示例代码
from abc import ABC, abstractmethod

class State(ABC):
    @abstractmethod
    def handle(self, context):
        pass

class StateA(State):
    def handle(self, context):
        print("State A handling. Moving to State B.")
        context.state = StateB()

class StateB(State):
    def handle(self, context):
        print("State B handling. Moving to State A.")
        context.state = StateA()

class Context:
    def __init__(self, state: State):
        self.state = state

    def request(self):
        self.state.handle(self)

# 测试
context = Context(StateA())
context.request()  # State A handling
context.request()  # State B handling
  1. 策略模式(Strategy Pattern)
    定义一组算法,将每个算法封装到独立的类中,使它们可以互相替换,且算法的变化不会影响客户端。
    示例代码
from abc import ABC, abstractmethod

# 策略接口
class Strategy(ABC):
    @abstractmethod
    def execute(self, data):
        pass

# 具体策略A
class StrategyA(Strategy):
    def execute(self, data):
        return f"Executing Strategy A with data {data}"

# 具体策略B
class StrategyB(Strategy):
    def execute(self, data):
        return f"Executing Strategy B with data {data}"

# 环境类
class Context:
    def __init__(self, strategy: Strategy):
        self.strategy = strategy

    def set_strategy(self, strategy: Strategy):
        self.strategy = strategy

    def do_work(self, data):
        return self.strategy.execute(data)

# 测试
context = Context(StrategyA())
print(context.do_work("test"))  # 使用策略A

context.set_strategy(StrategyB())
print(context.do_work("test"))  # 使用策略B
  1. 模板方法模式(Template Method Pattern)
    定义一个操作中的算法骨架,将某些步骤的实现延迟到子类中,使得子类可以在不改变算法结构的情况下重新定义特定步骤的实现。
    示例代码
from abc import ABC, abstractmethod

class AbstractClass(ABC):
    def template_method(self):
        self.step1()
        self.step2()
        self.step3()

    @abstractmethod
    def step1(self):
        pass

    def step2(self):
        print("Common step 2")

    @abstractmethod
    def step3(self):
        pass

class ConcreteClass(AbstractClass):
    def step1(self):
        print("ConcreteClass: step 1")

    def step3(self):
        print("ConcreteClass: step 3")

# 测试
obj = ConcreteClass()
obj.template_method()
  1. 访问者模式(Visitor Pattern)
    将操作分离到访问者类中,使新的操作可以灵活地添加到已存在的对象结构中,而不改变对象结构。
    代码示例
from abc import ABC, abstractmethod
import math

# 访问者抽象类
class Visitor(ABC):
    @abstractmethod
    def visit_circle(self, element):
        pass

    @abstractmethod
    def visit_rectangle(self, element):
        pass


# 具体访问者1: 计算面积
class AreaVisitor(Visitor):
    def visit_circle(self, circle):
        return math.pi * circle.radius ** 2

    def visit_rectangle(self, rectangle):
        return rectangle.width * rectangle.height


# 具体访问者2: 绘制形状
class DrawVisitor(Visitor):
    def visit_circle(self, circle):
        return f"Drawing a circle with radius {circle.radius}"

    def visit_rectangle(self, rectangle):
        return f"Drawing a rectangle with width {rectangle.width} and height {rectangle.height}"


# 元素抽象类
class Shape(ABC):
    @abstractmethod
    def accept(self, visitor):
        pass


# 具体元素1: 圆形
class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def accept(self, visitor):
        return visitor.visit_circle(self)


# 具体元素2: 矩形
class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def accept(self, visitor):
        return visitor.visit_rectangle(self)


# 测试访问者模式
if __name__ == "__main__":
    # 创建访问者
    area_visitor = AreaVisitor()
    draw_visitor = DrawVisitor()

    # 创建形状
    circle = Circle(radius=5)
    rectangle = Rectangle(width=4, height=6)

    # 使用访问者访问形状
    print("Area of Circle:", circle.accept(area_visitor))        # 计算圆形面积
    print("Area of Rectangle:", rectangle.accept(area_visitor)) # 计算矩形面积

    print(circle.accept(draw_visitor))       # 绘制圆形
    print(rectangle.accept(draw_visitor))    # 绘制矩形

III、实现设计原则

根据项目需求,选择正确的设计模式来贯彻相应的设计原则,从而提升代码的可维护性可扩展性灵活性

设计原则相关设计模式
单一职责原则建造者模式、代理模式、外观模式
开放封闭原则策略模式、装饰器模式、观察者模式、模板方法模式
里氏替换原则工厂方法模式、适配器模式、组合模式
依赖倒置原则抽象工厂模式、桥接模式、观察者模式、依赖注入
接口分离原则适配器模式、外观模式、代理模式、桥接模式
迪米特法则中介者模式、外观模式、命令模式
  1. 单一职责原则
    相关设计模式重在将职责分离,避免一个类承担过多功能。例如:

    • 建造者模式 用于将复杂对象的构建过程与表示分离;
    • 代理模式 用于分担访问控制的职责;
    • 外观模式 用于统一接口,简化对子系统的操作。
  2. 开放封闭原则
    这些设计模式都让系统通过“扩展功能”而非“修改代码”来提升灵活性。例如:

    • 策略模式 可以通过新增策略类实现不同行为;
    • 装饰器模式 通过动态给对象增加职责,扩展功能;
    • 观察者模式 通过订阅机制添加观察者,扩展系统行为;
    • 模板方法模式 允许子类通过覆盖固定流程中的某些步骤来扩展功能。
  3. 里氏替换原则
    相关模式保证子类可以安全替换父类,且行为一致。例如:

    • 工厂方法模式 通过返回合适的子类实例来满足替换;
    • 适配器模式 用于通过接口转换来使类能够兼容;
    • 组合模式 通过统一叶子节点和组合节点的操作,让整体和部分可替换。
  4. 依赖倒置原则
    这些模式强调通过依赖抽象来减少高层模块对低层模块的依赖。例如:

    • 抽象工厂模式 隐藏了具体对象的创建过程,使高层依赖抽象工厂而非实际类;
    • 桥接模式 将抽象部分和实现部分分离,通过接口编程实现解耦;
    • 观察者模式 通过抽象观察者和被观察者确保两者解耦;
    • 依赖注入 直接将依赖通过接口或构造方法传递,消除直接依赖。
  5. 接口分离原则
    强调让类只依赖它需要的最小接口,避免实现多余的功能。例如:

    • 适配器模式 能转换复杂接口为最符合需求的简单接口;
    • 外观模式 提供简化的接口与底层子系统交互;
    • 代理模式 提供更细化的接口以满足特定需要;
    • 桥接模式 分离接口与实现,让接口更加轻量和独立。
  6. 迪米特法则
    相关设计模式减少类与类之间的直接交互,通过中间类降低耦合度。例如:

    • 中介者模式 用中介者集中管理对象间的交互,避免对象之间直接通信;
    • 外观模式 提供高层接口隐藏底层细节,从而简化对象间的关系;
    • 命令模式 将请求的封装和执行全部通过命令对象处理,调用者与执行者互相隔离。

http://www.kler.cn/a/506793.html

相关文章:

  • leetcode hot100(2)
  • salesforce在opportunity的opportunity products页面增加一个按钮,可以批量删除products
  • postgresql分区表相关问题处理
  • 计算机组成原理(计算机系统3)--实验二:MIPS64乘法实现实验
  • Jmeter配置服务代理器 Proxy(二)
  • 数据库(MySQL)练习
  • 【Linux】10.Linux基础开发工具使用(3)
  • mysql community server社区版M2 macbook快速安装
  • 安卓与苹果系统安全性之比较
  • ip属地是根据手机号还是位置
  • MySQL中like模糊查询如何优化?
  • 【伪随机数】关于排序算法自测如何生成随机数而引发的……
  • C语言变长嵌套数组常量初始化定义技巧
  • 【排错记录】免密、nginx、cgroup、sshd
  • css 原子化
  • iOS页面设计:UIScrollView布局问题与应对策略
  • 【promethues 9090占用端口】没有网络,如何杀掉9090端口暂用的进程
  • Android 后台线程
  • 4. 使用springboot做一个音乐播放器软件项目【数据库表的创建】
  • 国产linux系统(银河麒麟,统信uos)使用 PageOffice 实现后台批量生成PDF文档
  • Math Reference Notes: 矩阵性质
  • python管理工具:conda部署+使用
  • 《黄金像凶杀案-再起》V1.2.0+Dlcs官方中文学习版
  • VIVADO FIFO (同步和异步) IP 核详细使用配置步骤
  • GO语言实现KMP算法
  • 代码随想录算法训练营第 9 天(字符串2)| 151.翻转字符串里的单词 卡码网55.右旋转字符串 KMP(跳过) 总结