Extract (Abstract Factory Method pattern) engineering (Factory Method pattern) singleton (singleton pattern) build (Builder pattern) primitive (prototype pattern)

Abstract factory method pattern

Provides an interface for creating a series of related or interdependent objects without specifying their concrete classes.

Example: Different manufacturers make different computers

abstract class Computer {
    abstract val name: String
}

class Dell : Computer() {
    override val name = "Dell"
}

class Asus : Computer() {
    override val name = "Asus"
}

class Acer : Computer() {
    override val name = "Acer"
}

class DellFactory : AbstractFactory() {
    override fun produce(a): Computer = Dell()
}

class AsusFactory : AbstractFactory() {
    override fun produce(a): Computer = Asus()
}

class AcerFactory : AbstractFactory() {
    override fun produce(a): Computer = Acer()
}

abstract class AbstractFactory() {
    abstract fun produce(a): Computer

    companion object {
        inline operator fun <reified T : Computer> invoke(a): AbstractFactory =
            when (T::class) {
                Dell::class -> DellFactory()
                Asus::class -> AsusFactory()
                Acer::class -> AcerFactory(a)else -> throw IllegalArgumentException()
            }
    }
}

fun main(a) {
    println(AbstractFactory<Dell>().produce().name)
    println(AbstractFactory<Asus>().produce().name)
    println(AbstractFactory<Acer>().produce().name)
}
Copy the code

Factory method pattern

Define an interface for creating objects and let subclasses decide which class to instantiate. Factory Method delays the instantiation of a class to subclasses.

Example: The same factory produces different products

abstract class Factory {
    abstract fun <T : Product> createProduct(cl: Class<T>): Product?
}

abstract class Product {
    abstract fun showInfo(a)
}

class ConcreateProductA : Product() {
    override fun showInfo(a) {
        println("I am concreate procuct A")}}class ConcreateProductB : Product() {
    override fun showInfo(a) {
        println("I am concreate procuct B")}}class ConcreateFactory : Factory() {
    override fun <T : Product> createProduct(cl: Class<T>): Product? {
        return Class.forName(cl.name).newInstance() as? T
    }
}

fun main(a) {
    val factory = ConcreateFactory()
    val productA = factory.createProduct(ConcreateProductA::class.java) productA? .showInfo()val productB = factory.createProduct(ConcreateProductB::class.java) productB? .showInfo() }Copy the code

The singleton pattern

Make sure there is only one example of a class, and instantiate it yourself and make it available to the entire system.

The hungry type

object Singleton1 {
    fun test(a) {
        println("I am hungry \ N")}}Copy the code

LanHanShi

class Singleton2 private constructor() {
    companion object {
        // Use Double Check Lock (DCL) internally to implement Double Check Lock
        val instance: Singleton2 by lazy { Singleton2() }
    }

    fun test(a) {
        println("I'm a slob.")}}Copy the code

use

fun main(a) {
    Singleton1.test()
    Singleton2.instance.test()
}
Copy the code

Builder model

Separating the construction of a complex object from its representation allows the same construction process to create different representations.

Example: Create a computer

class Computer {
    private lateinit var cpu: String
    private lateinit var ram: String
    private var usbCount: Int? = null
    private var keyboard: String? = null
    private var display: String? = null

    companion object {
        fun builder(cpu: String, ram: String): Builder {
            return Builder(cpu, ram)
        }
    }

    override fun toString(a): String {
        return "cpu=$cpu\nram=$ram\nusbCount=$usbCount\nkeyboard=$keyboard\ndisplay=$display\n"
    }

    class Builder(cpu: String, ram: String) {
        private val computer = Computer()

        init {
            computer.cpu = cpu
            computer.ram = ram
        }

        fun setUsbCount(usbCount: Int): Builder {
            computer.usbCount = usbCount
            return this
        }

        fun setDisplay(display: String): Builder {
            computer.display = display
            return this
        }

        fun build(a): Computer {
            return computer
        }
    }
}

val computer = Computer.builder(cpu = "intel", ram = "1")
    .setDisplay("1")
    .setUsbCount(3)
    .build()
Copy the code

Kotlin offers an easier way

// The easier way
data class Computer1(
    var cpu: String,
    var ram: String,
    var usbCount: Int? = null.var keyboard: String? = null.var display: String? = null
)

val computer1 = Computer1("intel"."1").apply {
    usbCount = 1
}
Copy the code

The prototype pattern

Specify what kind of objects to create with prototype instances, and create new objects by copying these prototypes.

data class Email(var recipient: String, varsubject: String? .var message: String?)

val email = Email("[email protected]"."hello"."hahahahha")
val copy = email.copy(recipient = "[email protected]")

fun main(a) {
    println("email = $email\n")
    println("copy email = $copy")}Copy the code