Ответ
Оба паттерна относятся к структурным, но решают разные проблемы.
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 — разводной мост между двумя берегами, чтобы они не срослись в одно неделимое говно. Всё, вопрос закрыт, иди работай.