中介者模式(Mediator Pattern)、桥接模式(Bridge Pattern) 和 策略模式(Strategy Pattern)

中介者模式(Mediator Pattern)桥接模式(Bridge Pattern)策略模式(Strategy Pattern) 都是常见的设计模式,它们解决不同类型的问题。我们将通过 Swift 示例来说明它们的使用场景,并附上简洁的图示。


1. 中介者模式(Mediator Pattern)

目的:中介者模式通过引入一个中介者对象,来减少类与类之间的直接耦合,避免多对多的依赖关系,使得系统中的类之间通过中介者进行交互。

使用场景

  • 当多个类之间的交互复杂且不易管理时,通过引入中介者模式可以减少各个类之间的依赖关系。
  • 适用于 UI 组件之间的交互,例如聊天系统中多个用户的消息传递,或多个模块之间的消息通知。

Swift 示例

假设我们有一个聊天系统,多个用户之间互相发送消息,使用中介者来协调消息的传递:

Swift 复制代码
// 中介者协议
protocol ChatMediator {
    func sendMessage(_ message: String, from user: User)
    func addUser(_ user: User)
}

// 用户类
class User {
    let name: String
    var mediator: ChatMediator?
    
    init(name: String) {
        self.name = name
    }
    
    func sendMessage(_ message: String) {
        mediator?.sendMessage(message, from: self)
    }
    
    func receiveMessage(_ message: String) {
        print("\(name) received message: \(message)")
    }
}

// 中介者实现
class ChatRoom: ChatMediator {
    private var users: [User] = []
    
    func addUser(_ user: User) {
        users.append(user)
        user.mediator = self
    }
    
    func sendMessage(_ message: String, from user: User) {
        for u in users where u !== user {
            u.receiveMessage(message)
        }
    }
}

// 使用中介者模式
let chatRoom = ChatRoom()

let user1 = User(name: "Alice")
let user2 = User(name: "Bob")
let user3 = User(name: "Charlie")

chatRoom.addUser(user1)
chatRoom.addUser(user2)
chatRoom.addUser(user3)

user1.sendMessage("Hello, everyone!")  // Alice 发送消息,Bob 和 Charlie 会收到消息

图示

Lua 复制代码
      +------------+
      | ChatRoom   |
      +------------+
            |
  +---------+----------+
  |         |          |
+---+     +---+      +---+
| A |     | B |      | C |
+---+     +---+      +---+

2. 桥接模式(Bridge Pattern)

目的:桥接模式的核心思想是将抽象与实现分离,使得二者可以独立扩展。通过桥接模式,你可以将类的功能分解为多个维度的类,并将这些维度的类组合起来,减少子类的数量。

使用场景

  • 当你需要将一个类的抽象部分与其实现部分解耦,使得二者可以独立地变化时。
  • 适用于设备控制系统、图形绘制系统等场景。

Swift 示例

假设我们有一个图形绘制系统,需要同时支持不同的形状(如圆形、方形)和不同的绘制方式(如矢量绘制、位图绘制):

Swift 复制代码
// 实现接口
protocol DrawingAPI {
    func drawCircle(radius: Double)
}

// 不同的绘制方式(实现)
class VectorDrawing: DrawingAPI {
    func drawCircle(radius: Double) {
        print("Drawing a vector circle with radius \(radius)")
    }
}

class RasterDrawing: DrawingAPI {
    func drawCircle(radius: Double) {
        print("Drawing a raster circle with radius \(radius)")
    }
}

// 抽象部分
protocol Shape {
    var drawingAPI: DrawingAPI { get }
    func draw()
}

// 圆形类
class Circle: Shape {
    var drawingAPI: DrawingAPI
    var radius: Double
    
    init(drawingAPI: DrawingAPI, radius: Double) {
        self.drawingAPI = drawingAPI
        self.radius = radius
    }
    
    func draw() {
        drawingAPI.drawCircle(radius: radius)
    }
}

// 使用桥接模式
let vectorDrawing = VectorDrawing()
let rasterDrawing = RasterDrawing()

let circle1 = Circle(drawingAPI: vectorDrawing, radius: 5)
circle1.draw()  // 输出: Drawing a vector circle with radius 5

let circle2 = Circle(drawingAPI: rasterDrawing, radius: 10)
circle2.draw()  // 输出: Drawing a raster circle with radius 10

图示

Lua 复制代码
  +------------------+
  |  Shape           |
  +------------------+
         ^
         |
    +------------+
    | Circle     |
    +------------+
         |
   +-------------+
   | DrawingAPI  |
   +-------------+
    /         \
   /           \
+--------+   +--------+
| Vector |   | Raster |
+--------+   +--------+

3. 策略模式(Strategy Pattern)

目的:策略模式用于将一系列的算法封装起来,让它们可以相互替换。策略模式让算法的变化独立于使用算法的客户端。

使用场景

  • 当你有多种算法,且希望在运行时决定使用哪种算法时。
  • 适用于需要动态选择算法或者行为的场景,比如支付方式选择、排序策略等。

Swift 示例

假设我们有一个应用,允许用户选择不同的排序算法:

复制代码

图示

Swift 复制代码
// 排序策略协议
protocol SortStrategy {
    func sort(_ data: [Int]) -> [Int]
}

// 具体的排序算法
class QuickSort: SortStrategy {
    func sort(_ data: [Int]) -> [Int] {
        return data.sorted()
    }
}

class MergeSort: SortStrategy {
    func sort(_ data: [Int]) -> [Int] {
        return data.sorted()
    }
}

class BubbleSort: SortStrategy {
    func sort(_ data: [Int]) -> [Int] {
        var array = data
        for i in 0..<array.count {
            for j in 0..<array.count-i-1 {
                if array[j] > array[j+1] {
                    array.swapAt(j, j+1)
                }
            }
        }
        return array
    }
}

// Context 使用策略模式
class SortContext {
    private var strategy: SortStrategy
    
    init(strategy: SortStrategy) {
        self.strategy = strategy
    }
    
    func setStrategy(_ strategy: SortStrategy) {
        self.strategy = strategy
    }
    
    func executeStrategy(data: [Int]) -> [Int] {
        return strategy.sort(data)
    }
}

// 使用策略模式
let context = SortContext(strategy: QuickSort())

let data = [5, 2, 9, 1, 5, 6]
let sortedData = context.executeStrategy(data: data)
print(sortedData)  // 输出: [1, 2, 5, 5, 6, 9]

// 切换排序算法
context.setStrategy(BubbleSort())
let bubbleSortedData = context.executeStrategy(data: data)
print(bubbleSortedData)  // 输出: [1, 2, 5, 5, 6, 9]

lua

Lua 复制代码
       +-----------------+
       | SortContext     |
       +-----------------+
              |
      +-------+--------+
      |                |
+-----------+     +-----------+
| QuickSort |     | BubbleSort |
+-----------+     +-----------+
      |                |
 +------------+   +------------+
 | MergeSort  |   | SortStrategy|
 +------------+   +------------+

总结对比表:

模式 目的/特点 使用场景 Swift 示例
中介者模式 降低类之间的耦合,通过中介者来协调交互 多个对象之间存在复杂交互时,避免直接引用其他对象 聊天系统中用户通过中介者交换消息
桥接模式 将抽象和实现分离,允许它们独立变化 抽象部分和实现部分变化频繁的场景 图形绘制系统,不同的形状和绘制方式
策略模式 将算法封装成独立的策略类,使得算法可以互换 需要根据不同情境使用不同算法的场景 排序算法的选择,可以动态切换不同的排序策略

这些设计模式帮助解决不同类型的耦合问题,允许我们编写更加灵活、可扩展、可维护的代码。根据实际需求选择合适的模式,可以提升代码的可维护性和复用性。

相关推荐
捕鲸叉5 小时前
C++软件设计模式之中介者模式
c++·设计模式·中介者模式
大包菜 cc6 小时前
使用工厂+策略模式实现去除繁琐的if else
简单工厂模式·策略模式
MinBadGuy16 小时前
【GeekBand】C++设计模式笔记17_Mediator_中介者模式
设计模式·中介者模式
蜗牛沐雨2 天前
使用 PyInstaller 和 hdiutil 打包 Tkinter 应用为 macOS 可安装的 DMG 文件
macos·策略模式
西海天际蔚蓝2 天前
使用策略模式时的一个生效问题
策略模式
zwh12984540602 天前
《C++设计模式》策略模式
c++·设计模式·策略模式
HEU_firejef2 天前
设计模式——策略模式
设计模式·策略模式
小馒头学python3 天前
PowerShell 常见问题解答
策略模式
冀晓武3 天前
C++ 设计模式:桥接模式(Bridge Pattern)
c++·设计模式·桥接模式
优美的赫蒂3 天前
WSL2桥接模式配置(可与外部设备互ping)
网络协议·tcp/ip·桥接模式