Меню

Главная
Случайная статья
Настройки
Фабричный метод (шаблон проектирования)
Материал из https://ru.wikipedia.org

Фабричный метод (англ. Factory Method), или виртуальный конструктор (англ. Virtual Constructor) — порождающий шаблон проектирования, предоставляющий подклассам (дочерним классам, субклассам) интерфейс для создания экземпляров некоторого класса. В момент создания наследники могут определить, какой класс создавать. Иными словами, данный шаблон делегирует создание объектов наследникам родительского класса. Это позволяет использовать в коде программы не конкретные классы, а манипулировать абстрактными объектами на более высоком уровне.

Содержание

Цель

Определяет интерфейс для создания объекта, но оставляет подклассам решение о том, на основании какого класса создавать объект. Фабричный метод позволяет классу делегировать создание подклассов. Используется, когда:
  • классу заранее неизвестно, объекты каких подклассов ему нужно создавать.
  • класс спроектирован так, чтобы объекты, которые он создаёт, специфицировались подклассами.
  • класс делегирует свои обязанности одному из нескольких вспомогательных подклассов, и планируется локализовать знание о том, какой класс принимает эти обязанности на себя.


Структура
  • Product — продукт
    • определяет интерфейс объектов, создаваемых абстрактным методом;
  • ConcreteProduct — конкретный продукт
    • реализует интерфейс Product;
  • Creator — создатель
    • объявляет фабричный метод, который возвращает объект типа Product. Может также содержать реализацию этого метода «по умолчанию»;
    • может вызывать фабричный метод для создания объекта типа Product;
  • ConcreteCreator — конкретный создатель
    • переопределяет фабричный метод таким образом, чтобы он создавал и возвращал объект класса ConcreteProduct.


Достоинства
  • позволяет сделать код создания объектов более универсальным, не привязываясь к конкретным классам (ConcreteProduct), а оперируя лишь общим интерфейсом (Product);
  • позволяет установить связь между параллельными иерархиями классов.


Недостатки
  • необходимость создавать наследника Creator для каждого нового типа продукта (ConcreteProduct).


Примеры кода

Kotlin
sealed interface Impact

data class Culture(val description: String) : Impact

data class Order(val description: String) : Impact

sealed interface Government {
    fun produceImpact(): Impact
}

data object DemocracyGovernment : Government {
    override fun produceImpact(): Impact {
        return Culture("Original Movies")
    }

}

data object AuthoritarianGovernment : Government {
    override fun produceImpact(): Impact {
        return Order("Public Security")
    }

}

class State(
    private val name: String, 
    private val government: Government
) {
    fun work() {
        println("State $name has made impact: ${government.produceImpact()}")
    }
}

fun main() {
    
    val dreamscapeState = State("Dreamscape Dominion", DemocracyGovernment)
    dreamscapeState.work()
    
    val nebulaState = State("Nebula Nations", AuthoritarianGovernment)
    nebulaState.work()
}


Swift
Downgrade Counter