В чем разница между паттернами Proxy и Bridge?

Ответ

Оба паттерна относятся к структурным, но решают разные проблемы.

Proxy (Заместитель)

  • Цель: Контроль доступа к объекту, добавление логики (ленивая загрузка, кэширование, защита, логирование) без изменения его основного кода.
  • Структура: Прокси и реальный объект реализуют один и тот же интерфейс. Клиент работает с прокси, который делегирует вызовы реальному объекту при необходимости.
  • Пример (Ленивая загрузка изображения):
    
    protocol Image {
    func display()
    }

class RealImage: Image { init(filename: String) { / Дорогая загрузка с диска / } func display() { print("Отображение изображения") } }

class ProxyImage: Image { private let filename: String private lazy var realImage: RealImage = RealImage(filename: filename) // Ленивая инициализация

init(filename: String) { self.filename = filename }
func display() { realImage.display() } // Реальный объект создаётся только здесь

}

// Использование let image: Image = ProxyImage(filename: "photo.jpg") image.display() // RealImage загружается и отображается только в этот момент


### Bridge (Мост)
*   **Цель:** Разделить абстракцию (интерфейс) и её реализацию, чтобы они могли изменяться независимо. Позволяет избежать наследования в виде "кубика Lego".
*   **Структура:** Абстракция содержит ссылку на объект реализации (через общий протокол). Можно комбинировать разные абстракции с разными реализациями.
*   **Пример (Графические примитивы и рендереры):**
```swift
// Реализация
protocol Renderer {
    func renderCircle(radius: Float)
}

class VectorRenderer: Renderer {
    func renderCircle(radius: Float) { print("Рисуем круг линиями (радиус: (radius))") }
}

class RasterRenderer: Renderer {
    func renderCircle(radius: Float) { print("Рисуем круг пикселями (радиус: (radius))") }
}

// Абстракция
class Shape {
    let renderer: Renderer
    init(renderer: Renderer) { self.renderer = renderer }
    func draw() {}
}

class Circle: Shape {
    let radius: Float
    init(radius: Float, renderer: Renderer) {
        self.radius = radius
        super.init(renderer: renderer)
    }
    override func draw() {
        renderer.renderCircle(radius: radius) // Делегирование реализации
    }
}

// Использование
let vectorCircle = Circle(radius: 5, renderer: VectorRenderer())
let rasterCircle = Circle(radius: 10, renderer: RasterRenderer())
vectorCircle.draw() // Рисуем круг линиями (радиус: 5.0)
rasterCircle.draw() // Рисуем круг пикселями (радиус: 10.0)

Итог: Proxy управляет доступом к одному объекту, Bridge разделяет иерархии абстракции и реализации.

Ответ 18+ 🔞

Давай я тебе на пальцах объясню, блядь, в чём тут разница, а то смотрю — глаза стеклянные, как у совы в полёте, ёпта.

Смотри, оба паттерна — структурные, это да. Но задачи у них, сука, как у молотка и отвёртки — вроде инструменты, а хуй перепутаешь.

Proxy (Заместитель, он же Подставная морда)

  • Суть: Это как твой личный секретарь-затычка, блядь. Хочешь поговорить с боссом? А он тебе: «Босс занят, нахуй». Или: «Босс спит, я за него всё подпишу». А может: «О, босс, я тебе тут логи все записал, кто звонил и что хотел». Цель — контролировать доступ к какому-то объекту, обвешать его дополнительной хуйнёй (ленивая загрузка, кэширование, защита, логирование), а сам объект даже не узнает, что его, блядь, проксируют.
  • Как устроен: Прокси и реальный объект — как близнецы-братья, ёпта. Они реализуют один и тот же интерфейс. Ты думаешь, что работаешь с реальным объектом, а на самом деле тебе подсунули подставу. Эта подстава решает, когда и как позвать настоящего.
  • Пример (Ленивая загрузка картинки):
    
    protocol Image {
    func display()
    }

class RealImage: Image { init(filename: String) { / Дорогая загрузка с диска, ебать её в сраку / } func display() { print("Отображение изображения") } }

class ProxyImage: Image { private let filename: String private lazy var realImage: RealImage = RealImage(filename: filename) // Ленивая инициализация, блядь!

init(filename: String) { self.filename = filename }
func display() { realImage.display() } // А вот тут-то, сука, реальный объект и родится!

}

// Использование let image: Image = ProxyImage(filename: "photo.jpg") // Ничего не грузится, расслабься image.display() // А вот щас, блядь, понеслась! RealImage загружается и отображается только в этот момент.

Видишь? Прокси — это охранник на проходной. Хочешь внутрь — пройди через него.

### Bridge (Мост, он же Разводной мост между хуйнёй и пиздой)
*   **Суть:** А вот это уже поинтереснее. Представь, что у тебя есть, блядь, «форма» (круг, квадрат) и «способ её нарисовать» (векторно, растрово, пальцем по экрану). Так вот, Bridge говорит: «Давайте, сука, не будем плодить хуйню!». Не надо создавать класс `VectorCircle`, `RasterCircle`, `VectorSquare`, `RasterSquare` — овердохуища классов получится. Лучше разделим эти две идеи, как грешника от праведника.
*   **Как устроен:** Абстракция (форма) содержит ссылку на объект реализации (рендерер) через общий протокол. И они живут отдельно, не мешая друг другу! Хочешь новую форму — добавь, не трогая рендереры. Хочешь новый рендерер (например, 3D-рендерер, ёпта) — добавь, не трогая формы. Красота, блядь!
*   **Пример (Графические примитивы и рендереры):**
```swift
// Реализация (чем рисовать)
protocol Renderer {
    func renderCircle(radius: Float)
}

class VectorRenderer: Renderer {
    func renderCircle(radius: Float) { print("Рисуем круг линиями, красиво, блядь (радиус: (radius))") }
}

class RasterRenderer: Renderer {
    func renderCircle(radius: Float) { print("Рисуем круг пикселями, квадратными, сука (радиус: (radius))") }
}

// Абстракция (что рисовать)
class Shape {
    let renderer: Renderer // Мост, блядь! Связующее звено!
    init(renderer: Renderer) { self.renderer = renderer }
    func draw() {}
}

class Circle: Shape {
    let radius: Float
    init(radius: Float, renderer: Renderer) {
        self.radius = radius
        super.init(renderer: renderer)
    }
    override func draw() {
        renderer.renderCircle(radius: radius) // Делегирование, сука, реализации! Форма говорит рендереру: «Нарисуй меня!»
    }
}

// Использование
let vectorCircle = Circle(radius: 5, renderer: VectorRenderer()) // Круг + вектор
let rasterCircle = Circle(radius: 10, renderer: RasterRenderer()) // Тот же круг, но + растр
vectorCircle.draw() // Рисуем круг линиями (радиус: 5.0)
rasterCircle.draw() // Рисуем круг пикселями (радиус: 10.0)

Итог, блядь, резюмирую:

  • Proxy — это один объект и его охранник/помощник/прилипала. Управляет доступом к конкретной сущности.
  • Bridge — это развод двух больших идей, чтобы они не ебали друг другу мозг. Разделяет абстракцию и реализацию, чтобы можно было комбинировать их как угодно, без ада на inheritance.

Понял разницу? Proxy — подстава для одного чувака. Bridge — разводной мост между двумя берегами, чтобы они не срослись в одно неделимое говно. Всё, вопрос закрыт, иди работай.