图案桥

桥接模式是指结构设计模式。它允许您通过将逻辑移动到单独的抽象类中来抽象类逻辑的实现。听起来很简单,对吧?

假设我们实现一个垃圾邮件机器人,它应该能够向不同类型的信使发送消息。
我们使用通用协议来实现它:

protocol User {
    let token: String
    let username: String
}

protocol Messenger {
    var authorize(login: String, password: String)
    var send(message: String, to user: User)
}

class iSeekUUser: User {
    let token: String
    let username: String
}

class iSeekU: Messenger {

    var authorizedUser: User?
    var requestSender: RequestSender?
    var requestFactory: RequestFactory?

    func authorize(login: String, password: String) {
        authorizedUser = requestSender?.perform(requestFactory.loginRequest(login: login, password: password))
    }
    
    func send(message: String, to user: User) {
        requestSender?.perform(requestFactory.messageRequest(message: message, to: user)
    }
}

class SpamBot {
    func start(usersList: [User]) {
        let iSeekUMessenger = iSeekU()
        iSeekUMessenger.authorize(login: "SpamBot", password: "SpamPassword")
        
        for user in usersList {
            iSeekUMessennger.send(message: "Hey checkout demensdeum blog! http://demensdeum.com", to: user)
        }
    }
}

现在让我们想象一下,用于为 iSekU Messenger 发送消息的新的、更快的协议的发布。要添加新协议,您需要复制 iSekU 机器人的实现,仅更改其中的一小部分。如果只改变了一小部分类逻辑,则不清楚为什么要这样做。这种做法违反了 DRY 原则;随着产品的进一步开发,新功能的实现会出现错误和延迟,从而体现出缺乏灵活性。
让我们将协议的逻辑转移到一个抽象类中,从而实现桥接模式:

protocol User {
    let token: String
    let username: String
}

protocol Messenger {
    var authorize(login: String, password: String)
    var send(message: String, to user: User)
}

protocol MessagesSender {
    func send(message: String, to user: User)
}

class iSeekUUser: User {
    let token: String
    let username: String
}

class iSeekUFastMessengerSender: MessagesSender {
    func send(message: String, to user: User) {
        requestSender?.perform(requestFactory.messageRequest(message: message, to: user)
    }
}

class iSeekU: Messenger {

    var authorizedUser: User?
    var requestSender: RequestSender?
    var requestFactory: RequestFactory?
    var messagesSender: MessengerMessagesSender?

    func authorize(login: String, password: String) {
        authorizedUser = requestSender?.perform(requestFactory.loginRequest(login: login, password: password))
    }
    
    func send(message: String, to user: User) {
        messagesSender?.send(message: message, to: user)
    }
}

class SpamBot {

    var messagesSender: MessagesSender?

    func start(usersList: [User]) {
        let iSeekUMessenger = iSeekU()
        iSeekUMessenger.authorize(login: "SpamBot", password: "SpamPassword")
        
        for user in usersList {
            messagesSender.send(message: "Hey checkout demensdeum blog! http://demensdeum.com", to: user)
        }
    }
}

这种方法的优点之一无疑是能够通过编写实现抽象逻辑的插件/库来扩展应用程序的功能,而无需更改主应用程序的代码。
与策略模式有什么区别?两种模式非常相似,但是,策略描述了切换*算法*,而桥接允许您切换大部分*任何复杂逻辑*。

来源

https://refactoring.guru/ru/design-patterns/bridge

源代码

https://gitlab.com/demensdeum/patterns/ p>

Leave a Comment

Your email address will not be published. Required fields are marked *