Описание
Гарантирует, что у класса есть только один экземпляр, и предоставляет глобальную точку доступа к нему.
Реализация
object Singleton {
fun log(message: String) = println(message)
}
// Использование:
Singleton.log("Hello, Singleton!")
Описание
Делегирует создание объектов подклассам, позволяя изменять тип создаваемых объектов.
Реализация
interface Animal {
fun speak()
}
class Dog : Animal {
override fun speak() = println("Гав!")
}
class AnimalFactory {
fun createAnimal(): Animal = Dog()
}
// Использование:
val factory = AnimalFactory()
val animal = factory.createAnimal()
Описание
Создаёт семейства связанных объектов без указания их конкретных классов.
Реализация
interface Button {
fun render()
}
class WindowsButton : Button {
override fun render() = println("Отрисована кнопка Windows")
}
interface GUIFactory {
fun createButton(): Button
}
class WindowsFactory : GUIFactory {
override fun createButton() = WindowsButton()
}
// Использование:
val factory: GUIFactory = WindowsFactory()
val button = factory.createButton()
Описание
Поэтапно конструирует сложные объекты, разделяя процесс создания от его представления.
Реализация
class Pizza(
val dough: String,
val toppings: List<String>
) {
class Builder(private val dough: String) {
private val toppings = mutableListOf<String>()
fun addTopping(topping: String) = apply { toppings.add(topping) }
fun build() = Pizza(dough, toppings)
}
}
// Использование:
val pizza = Pizza.Builder("тонкое тесто")
.addTopping("сыр")
.build()
Описание
Копирует существующие объекты, избегая зависимости от их классов.
Реализация
data class Robot(val id: String) : Cloneable {
public override fun clone() = Robot(id)
}
// Использование:
val original = Robot("R2-D2")
val cloned = original.clone()
Описание
Адаптирует интерфейс класса к другому интерфейсу, который ожидают клиенты.
Реализация
class LegacyPrinter {
fun printLegacy() = println("Печать в старом формате")
}
interface ModernPrinter {
fun print()
}
class PrinterAdapter(private val legacyPrinter: LegacyPrinter) : ModernPrinter {
override fun print() = legacyPrinter.printLegacy()
}
// Использование:
val adapter = PrinterAdapter(LegacyPrinter())
adapter.print()
Описание
Динамически добавляет объекту новые обязанности, оборачивая его в обёртки.
Реализация
interface Coffee {
fun cost(): Double
}
class Espresso : Coffee {
override fun cost() = 2.0
}
class MilkDecorator(private val coffee: Coffee) : Coffee {
override fun cost() = coffee.cost() + 0.5
}
// Использование:
val coffee: Coffee = MilkDecorator(Espresso())
println(coffee.cost()) // 2.5
Описание
Упрощает взаимодействие со сложной системой, предоставляя упрощённый интерфейс.
Реализация
class CPU {
fun start() = println("CPU запущен")
}
class ComputerFacade {
private val cpu = CPU()
fun start() = cpu.start()
}
// Использование:
ComputerFacade().start()
Описание
Объединяет объекты в древовидные структуры для работы с ними как с единым целым.
Реализация
interface Component {
fun operation()
}
class Leaf : Component {
override fun operation() = println("Лист выполняет операцию")
}
class Composite : Component {
private val children = mutableListOf<Component>()
fun add(component: Component) = children.add(component)
override fun operation() = children.forEach { it.operation() }
}
// Использование:
val composite = Composite()
composite.add(Leaf())
composite.operation()
Описание
Контролирует доступ к объекту, добавляя дополнительную логику (например, ленивую загрузку).
Реализация
interface Image {
fun display()
}
class RealImage(private val path: String) : Image {
override fun display() = println("Изображение $path отображено")
}
class ProxyImage(private val path: String) : Image {
private var realImage: RealImage? = null
override fun display() {
if (realImage == null) realImage = RealImage(path)
realImage!!.display()
}
}
// Использование:
val image: Image = ProxyImage("photo.jpg")
image.display()
Описание
Уведомляет зависимые объекты об изменении состояния наблюдаемого объекта.
Реализация
interface Observer {
fun update(event: String)
}
class User : Observer {
override fun update(event: String) = println("Событие: $event")
}
class EventManager {
private val observers = mutableListOf<Observer>()
fun subscribe(observer: Observer) = observers.add(observer)
fun notify(event: String) = observers.forEach { it.update(event) }
}
// Использование:
val manager = EventManager()
manager.subscribe(User())
manager.notify("Новое обновление!")
Описание
Инкапсулирует алгоритмы в отдельные классы, делая их взаимозаменяемыми.
Реализация
interface PaymentStrategy {
fun pay(amount: Double)
}
class CreditCardPayment : PaymentStrategy {
override fun pay(amount: Double) = println("Оплата картой: $amount")
}
class PaymentContext(private var strategy: PaymentStrategy) {
fun executePayment(amount: Double) = strategy.pay(amount)
}
// Использование:
val context = PaymentContext(CreditCardPayment())
context.executePayment(100.0)
Описание
Инкапсулирует запросы как объекты, позволяя параметризовать клиенты запросами.
Реализация
interface Command {
fun execute()
}
class LightOnCommand(private val light: Light) : Command {
override fun execute() = light.turnOn()
}
class Light {
fun turnOn() = println("Свет включён")
}
// Использование:
val command = LightOnCommand(Light())
command.execute()
Описание
Передаёт запрос по цепочке обработчиков, пока один из них не обработает его.
Реализация
abstract class Handler {
var next: Handler? = null
abstract fun handle(request: String)
}
class AuthHandler : Handler() {
override fun handle(request: String) {
if (request == "auth") println("Обработана авторизация")
else next?.handle(request)
}
}
// Использование:
val handler = AuthHandler()
handler.handle("auth")
Описание
Последовательно обходит элементы коллекции без раскрытия её внутренней структуры.
Реализация
class BookCollection(private val books: List<String>) {
fun iterator() = object : Iterator<String> {
private var index = 0
override fun hasNext() = index < books.size
override fun next() = books[index++]
}
}
// Использование:
val collection = BookCollection(listOf("Книга 1", "Книга 2"))
val iterator = collection.iterator()
while (iterator.hasNext()) println(iterator.next())
Каждая реализация на Kotlin демонстрирует основную идею шаблона. Для упрощения опущены детали вроде потокобезопасности и обработки ошибок, но в реальных проектах их необходимо учитывать.