파게로그

[OOP] Object, singleton pattern 본문

콤퓨타 왕기초/Kotlin

[OOP] Object, singleton pattern

파게 2021. 6. 13. 10:56

Object Declarations

Singleton은 객체지향 프로그래밍의 패턴 중 하나로서, 어떤 클래스가 하나의 인스턴스만을 가진다는 것이다. 예를 들어, SQL 데이터베이스 백엔드를 가지는 애플리케이션을 만들 때, 모든 고객에 대해 동일한 데이터베이스 연결을 재사용할 수 있도록 하기 위해 connection pool을 만들고 싶을 수 있다. 이를 위해서는 connection을 singleton class로 생성함으로써 모든 고객이 동일한 connection을 획득하도록 할 수 있다.

 

Kotlin은 object declaration 기능을 통해 singletons을 쉽게 사용할 수 있는 방법을 제공한다. 이를 위해 object 키워드가 사용된다.

object 선언은 properties, methods 등을 포함할 수 있다. 그러나, 당연하게도 생성자를 가지는 것은 허용되지 않는다.

일반적인 클래스와 마찬가지로, 메서드를 호출할 수 있고 .을 이용해 properties에 접근할 수 있다. 또한 다른 보통의 클래스처럼, 클래스를 상속한다거나 인터페이스를 구현한다거나 하는 것도 가능하다.

 

object Connection {
    var id: String = "unknown"
    var pw: String = "unknown"

    fun getStatus() {
        println("fine")
    }
}

fun main() {
    // var connection = Connection() // NOT allowed to have constructors
    var connection1 = Connection
    var connection2 = Connection

    println(connection1 == connection2)
}

 

 

 

Singletons and Dependency Injection

object 선언은 종종 유용할 수 있지만, 시스템의 많은 다른 부분과 상호작용하는 대규모 소프트웨어 시스템에서는 이상적이지 않을 수 있다.

 

 

 

Kotlin object Expressions

object 키워드는 anonymous objects라고 알려진 익명 클래스의 객체를 생성하는 데에도 사용될 수 있다. 어떤 클래스나 인터페이스의 subclass를 선언하지 않고도 약간의 변경을 가한 객체를 생성할 때 사용하는 것이다. 예를 들면 아래와 같다.

window.addMouseListener(object : MouseAdapter() {
    override fun mouseClicked(e: MouseEvent) {
        // ...
    }

    override fun mouseEntered(e: MouseEvent) {
        // ...
    }
})

위 프로그램에서 익명 object는 MouseAdapter 클래스를 상속받는 것으로 선언되었으며, MouseAdapter의 두 개의 메서드를 오버라이드한다.

필요하다면, 익명 객체에 이름을 할당하여 변수에 저장할 수 있다.

val obj = object : MouseAdapter() {
    override fun mouseClicked(e: MouseEvent) {
        // ...
    }

    override fun mouseEntered(e: MouseEvent) {
        // ...
    }
}

 

예시가 황당하긴 한데 programiz는 다음과 같은 예시 코드를 제공한다. 내가 다른 걸로 바꾸어야겠다...

open class Person() {
    fun eat() = println("Eating food.")

    fun talk() = println("Talking with people.")

    open fun pray() = println("Praying god.")
}

fun main(args: Array<String>) {
    val atheist = object : Person() {
        override fun pray() = println("I don't pray. I am an atheist.")
    }

    atheist.eat()
    atheist.talk()
    atheist.pray()
}

 

 

만약 익명 객체를 선언할 때 구현하는 클래스가 생성자를 가지고 있다면, 생성자의 파라미터에 적절한 값을 전달해야 한다. 예시는 아래 코드와 같다.

 

open class Person(name: String, age: Int) {

    init {
        println("name: $name, age: $age")
    }

    fun eat() = println("Eating food.")
    fun talk() = println("Talking with people.")
    open fun pray() = println("Praying god.")
}

fun main(args: Array<String>) {
    val atheist = object : Person("Jack", 29) {
        override fun pray() = println("I don't pray. I am an atheist.")
    }

    atheist.eat()
    atheist.talk()
    atheist.pray()
}

'콤퓨타 왕기초 > Kotlin' 카테고리의 다른 글

[OOP] 연산자 오버로딩  (0) 2021.06.13
[OOP] Extension Function  (0) 2021.06.13
[OOP] Sealed Classes  (0) 2021.06.13
[OOP] Data Class  (0) 2021.06.13
[OOP] Nested class and Inner class  (0) 2021.06.13
Comments