보뇨 다이어리

코틀린 디자인 패턴 - 구조 패턴 이해하기 (데코레이터) 본문

컴퓨터 관련/Kotlin 정보

코틀린 디자인 패턴 - 구조 패턴 이해하기 (데코레이터)

보뇨 2024. 11. 28. 15:04
반응형

구조패턴은 쓸내용이 많아서 각각 필요한것대로 정리

 

개인적인 생각이지만 일부 프록시 패턴과 동일한 구조로 가져가는데 대신에 by 연산자를 통해서 그게 눈에 띄기때문에 나쁘지않아보임.

require 메소드 또한 가독성이 의외로 좋아서 (처음에는 어색하지만...ㅠ) 코틀린 철학과 잘맞는 코드형태인거같음.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
    @Test
    fun decoratorTest() {
        val defaultStarTrekRepository = DefaultStarTrekRepository()
        val validatingAddRepository = ValidatingAdd(defaultStarTrekRepository)
        val repository: StarTrekRepository = LoggingGetCaptain(validatingAddRepository)
 
        val result1 = repository.getCaptain("USS")
        repository.addCaptain("hello", "bab")
        val result2 = repository.getCaptain("hello")
        println("$result1, $result2") // 장뤽 피카드, bab
 
        // 연산자 오버로딩
        val result3 = repository["USS"]
        repository["hello"] = "bab"
        val result4 = repository["hello"]
        println("$result3, $result4") // 장뤽 피카드, bab
    }
 
    interface StarTrekRepository {
        fun getCaptain(starshipName: String): String
        fun addCaptain(starshipName: String, captainName: String)
        operator fun get(starshipName: String): String
        operator fun set(starshipName: String, captainName: String)
    }
 
    class DefaultStarTrekRepository : StarTrekRepository {
        private val starshipCaptains = mutableMapOf("USS" to "장뤽 피카드")
 
        override fun getCaptain(starshipName: String): String {
            return starshipCaptains[starshipName] ?: "알수없음"
        }
 
        override fun addCaptain(starshipName: String, captainName: String) {
            starshipCaptains[starshipName] = captainName
        }
 
        override fun get(starshipName: String): String {
            return getCaptain(starshipName)
        }
 
        override fun set(starshipName: String, captainName: String) {
            addCaptain(starshipName, captainName)
        }
    }
 
    class LoggingGetCaptain(private val repository: StarTrekRepository): StarTrekRepository by repository {
        override fun getCaptain(starshipName: String): String {
            println("$starshipName 함선의 선장을 조회하는중입니다.")
            return repository.getCaptain(starshipName)
        }
    }
 
    class ValidatingAdd(private val repository: StarTrekRepository): StarTrekRepository by repository {
        private val maxNameLength = 7
 
        override fun addCaptain(starshipName: String, captainName: String) {
            require (captainName.length < maxNameLength) {
                "$captainName 의 이름이 7자를 넘습니다."
            }
 
            repository.addCaptain(starshipName, captainName)
        }
    }
cs
반응형