[Kotlin] 디자인패턴 (2) - 스트래티지 패턴

Kotlin 스트래티지 패턴

Posted by 동식이 블로그 on June 2, 2020

Kotlin 객체지향 디자인 패턴

Java 객체지향 디자인 패턴 책을 보고 Kotlin으로 변환하면서 공부한 내용입니다

Java객체지향 디자인패턴

5장. 스트래티지 패턴

  1. 스트래티지 패턴

  • 전략을 쉽게 바꿀 수 있도록 해주는 디자인 패턴이다. 전략이란 어떤 목적을 달성하기 위해 일을 수행하는 방식, 비즈니스 규칙, 문제를 해결하는 알고리즘 등으로 이해할 수 있다.
  • 스트래티지 패턴은 같은 문제를 해결하는 여러 알고리즘이 클래스별로 캡슐화되어 있고 이들이 필요할 때 교체할 수 있도록 함으로써 동일한 문제를 다른 알고리즘으로 해결할 수 있게 하는 디자인 패턴이다.

5-1

  • Strategy : 인터페이스나 추상 클래스로 외부에서 동일한 방식으로 알고리즘을 호출하는 방법을 명시한다.
  • ConcreateStrategy1,ConcreateStrategy2,ConcreateStrategy3 : 스트래티지 패턴에서 명시한 알고리즘을 실제로 구현한 클래스다.
  • Context : 스트래티지 패턴을 이용하는 역할을 수행한다. 필요에 따라 동적으로 구체적인 전략을 바꿀수 있도록 setter 메서드를 제공한다.
  1. 로봇만들기 예제

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
abstract class Robot(private val name: String) {
    fun getName(): String = name
    abstract fun attack()
    abstract fun move()
}

class TaekwonV(name: String) : Robot(name) {
    override fun attack() {
        println("i have missile and can attack with it")
    }

    override fun move() {
        println("i can only walk")
    }
}

class Atom(name: String) : Robot(name) {
    override fun attack() {
        println("i have strong punch and can attack with it")
    }
    
    override fun move() {
        println("i can only fly")
    }
}

fun client() {
    val taekwonV: Robot = TaekwonV("TaekwonV")
    val atom: Robot = Atom("Atom")
    println("my name is ${taekwonV.getName()}")
    taekwonV.move()
    taekwonV.attack()
    
    println("my name is ${atom.getName()}")
    atom.move()
    atom.attack()
}

client()
  1. 문제점

  • 기존 로봇의 공격 또는 이동 방법을 수정하려면 어떤 변경 작업을 해야 하는가?
  • 새로운 로봇을 만들어 기존의 공격 또는 이동 방법을 추가하거나 수정하려면?
  1. 해결책

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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
abstract class Robot(private val name: String) {
    private lateinit var movingStrategy: MovingStrategy
    private lateinit var attackStrategy: AttackStrategy

    fun getName(): String = name
    fun setMovingStrategy(movingStrategy: MovingStrategy) {
        this.movingStrategy = movingStrategy
    }

    fun setAttackStrategy(attackStrategy: AttackStrategy) {
        this.attackStrategy = attackStrategy
    }

    fun attack() {
        attackStrategy.attack()
    }

    fun move() {
        movingStrategy.move()
    }

}

class TaekwonV(name: String) : Robot(name) {}

class Atom(name: String) : Robot(name) {}

interface MovingStrategy {
    fun move()
}

class FlyingStrategy : MovingStrategy {
    override fun move() {
        println("i can fly")
    }
}

class WalkingStrategy : MovingStrategy {
    override fun move() {
        println("i can walk")
    }
}

interface AttackStrategy {
    fun attack()
}

class MissileStrategy : AttackStrategy {
    override fun attack() {
        println("i have missile and can attack with it")
    }
}

class PunchStrategy : AttackStrategy {
    override fun attack() {
        println("i have strong punch and can attack with it")
    }
}

fun client() {
    val taekwonV: Robot = TaekwonV("TaekwonV")
    val atom: Robot = Atom("Atom")
    
    taekwonV.setMovingStrategy(WalkingStrategy())
    taekwonV.setAttackStrategy(MissileStrategy())
    
    atom.setMovingStrategy(FlyingStrategy())
    atom.setAttackStrategy(PunchStrategy())
    
    println("my name is ${taekwonV.getName()}")
    taekwonV.move()
    taekwonV.attack()
    
    println("my name is ${atom.getName()}")
    atom.move()
    atom.attack()
}

client()