Motivation: We want to create an object whose concrete type may vary, but the code for constructing and using the object should not depend on that concrete type.
Intent: Define an interface for creating objects in a superclass, but let subclasses decide which class to instantiate.
// Products
interface Button { fun render() }
class WindowsButton : Button { fun render() { /* ... */ } }
class HtmlButton : Button { fun render() { /* ... */ } }
// Creators
abstract class Dialog {
// factory method
abstract fun createButton(): Button
// operation
fun render() {
val button = createButton()
button.render()
}
}
class WindowsDialog : Dialog() {
override fun createButton(): Button = WindowsButton()
}
class WebDialog : Dialog() {
override fun createButton(): Button = HtmlButton()
}This effectively designs a workflow for creating an object but defers the specific type to subclasses.
See Abstract Factory