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