전략 패턴
알고리즘 및 로직을 따로 정의하여 필요에 의해 사용 또는 교체 할 수 있는 패턴.
검색으로 예를 들면 전체/운동/it/패션 이런식으로 종류를 나눠서 검색할 수 있을것이다.
이때 전략 패턴을 사용하면 인터페이스를 구현한 그 클래스 부분만 바꾸면 코드 수정이 좀 더 쉽지 않을까?
말로만 보면 내가 적어놔도 모르겠다.. 코드를 통해 예시를 만들자!
예시는 모두가 즐겨하고 내가 즐겨하는 리그오브레전드로 하였습니다.
interface skil {
fun Q()
fun W()
fun E()
fun R()
}
class Syndra:skil {
override fun Q() {
println("어둠 구체")
}
override fun W() {
println("의지의 힘")
}
override fun E() {
println("적군 와해")
}
override fun R() {
println("풀려난 힘")
}
}
class Summoner {
val GoldSyndra = Syndra()
val DiamondSyndra = Syndra()
}
fun main() {
val user = Summoner()
user.GoldSyndra.Q()
user.DiamondSyndra.Q()
}
이렇게만 해도 신드라가 스킬을 사용하는데는 별 이상이 없다.
골드 신드라든 다이아몬드 신드라든 아이언이든 챌린저든 어디 티어든 신드라가 사용하는 스킬은 같으니깐
그러나 심해를 가여이 여긴 라이엇이 갑자기 티어별 승률 차이가 심한 챔피언에 한해 티어별 스킬을 개편한다고 치자 그 대상으로 신드라가 첫 패치 대상이 되었다.
패치 내역 - 다이아몬드 티어 미만 신드라의 스킬이 2회 충전형으로 변경됩니다.
Q 스킬명 변경 - 어둠 폭발
W 스킬명 변경 - 초월의 힘
R 스킬명 변경 - 태초의 힘
이럴일은 없겠지만 이렇게 패치되었다고 치자.
현재와 같은 구조론 interface의 스킬을 구현해서 스킬을 사용하기 때문에 티어별 신드라의 스킬을 변경하려면 신드라 챔피언에 관한 인터페이스를 새로 만들거나 다이아몬드 티어 미만 소환사 or 신드라 클래스를 따로 만들어야 할 것이다.
이 과정을 해결하기 위해 전략 패턴으로 코드를 바꾸어보겠다.
class SetOverDiamondTier():skil{
override fun Q() {
println("어둠 구제")
}
override fun W() {
println("의지의 힘")
}
override fun E() {
println("적군 와해")
}
override fun R() {
println("풀려난 힘")
}
}
class SetUnderDiamondTier():skil{
override fun Q() {
println("어둠 폭발")
}
override fun W() {
println("초월의 힘")
}
override fun E() {
println("적군 와해")
}
override fun R() {
println("태초의 힘")
}
}
class Syndra {
private lateinit var tier_Skil:skil
public fun setSKil(syndraSkil: skil) {
this.tier_Skil=syndraSkil
}
fun showSkil(){
tier_Skil.Q()
tier_Skil.W()
tier_Skil.E()
tier_Skil.R()
}
}
skil이라는 인터페이스를 구현한 두 클래스를 만든 후(알고리즘 및 로직을 따로 정의)
신드라 클래스에선 setSkil이라는 함수의 매개변수 타입을 skil로 두어
특정 티어대 스킬을 넣으면 현재 신드라 클래스의 스킬을 그 특정 티어대 스킬로 변경하게 그리고 적용 됐는지 확인하기 위해 showSkil 함수를 정의해주었다.
class Summoner {
val bronzeSyndra = Syndra()
val diaMondSyndra = Syndra()
}
소환사 클래스에선 변수명만 다른 같은 신드라 클래스를 선언 해주었다
이제 메인문에서 테스트를 해보자
fun main() {
val user = Summoner()
val bronzeSkil = SetUnderDiamondTier()
val diamondSkil = SetOverDiamondTier()
user.bronzeSyndra.setSKil(bronzeSkil)
user.diaMondSyndra.setSKil(diamondSkil)
println("다이아")
user.diaMondSyndra.showSkil()
println("----------------------")
println("브론즈")
user.bronzeSyndra.showSkil()
}
결과는???
아주 잘나온다
이것으로 Stratergy 패턴을 알아보았다
티어가 다른 신드라 객체가 100개가 넘는데 처음 방식으로 각 티어별 스킬을 맞춰 주려면 객체 생성때마다 함수를 바꿔줘야 할것이다 그리고 바꾸는 과정에 그리고 Solid 원칙의 OCP 원칙을 위반 할지도?(인터페이스의 함수 구현을 수정해야 되니깐)
이러한 점을 개선하기 위해 나온 패턴이 아닌가 싶다.
아직까지 잘 모르겠다...
잘못된점이 있으면 댓글로 지적 부탁드립니다.