오목 미션을 진행하면서 렌주룰의 금수를 처음 알게 되었다.
렌주룰의 금수 : 먼저 시작하는 흑돌이 무조건 유리하기 때문에 흑목은 3-3, 4-4, 장목 등을 금지한다.
예를 들어 다음과 같은 경우가 3-3 이고 가운데에 흑돌을 놓을 수 없다.
3-3, 4-4 는 다른 사람의 코드를 사용했고 장목은 직접 만들어 사용했다.
override fun isForbidden(location: Location) =
OmokForbiddenRuleAdapter(board, stone).isForbidden(location) ||
OmokLongForbidden.isForbidden(board, location, stone)
그러다보니 위와 같이 코드를 작성했다.
가독성도 떨어지고 확장성이 떨어져서 좋지 못한 구조이다.
그래서 적용해본 것은 데코레이터 패턴!
데코레이터 패턴은 객체에 추가적인 기능을 동적으로 더할 수 있도록 하는 패턴이다.
즉, 기존 객체를 변경하지 않고 새로운 기능을 추가할 수 있다.
이론적으로 자세한 내용을 알고 싶으면 추천!
https://en.wikipedia.org/wiki/Decorator_pattern
데코레이터 패턴 적용하기
먼저 OmokForbiddenRule (오목 금수 룰) interface를 정의한다.
금수룰은 금수인지 확인하고 Boolean 을 반환한다.
interface OmokForbiddenRule {
fun isForbidden(location: Location): Boolean
}
이 인터페이스를 구현하는 클래스 3-3, 4-4, 장목 룰을 정의한다.
이때 3-3, 4-4 는 다른 사람의 코드를 사용한 OmokForbiddenUseOtherRule 을 상속받도록 했다.
class OmokThreeForbidden(board: Board, currentStone: Stone) : OmokForbiddenRule,
OmokForbiddenUseOtherRule(board, currentStone) {
override fun isForbidden(location: Location): Boolean {
...
}
}
class OmokFourForbidden(board: Board, currentStone: Stone) : OmokForbiddenRule,
OmokForbiddenUseOtherRule(board, currentStone) {
override fun isForbidden(location: Location): Boolean {
...
}
}
class OmokLongForbidden(private val board: Board, private val stone: Stone) : OmokForbiddenRule {
override fun isForbidden(location: Location): Boolean {
...
}
}
그런 다음 OmokForbiddenRuleAdapter 를 만든다.
Adapter 도 OmokForbiddenRule 를 상속 받는 것이 핵심이다.
class OmokForbiddenRuleAdapter(board: Board, private val currentStone: Stone) :
OmokForbiddenRule {
private val forbiddenRulesByStone = mapOf(
Stone.BLACK to listOf(
OmokThreeForbidden(board, currentStone),
OmokFourForbidden(board, currentStone),
OmokLongForbidden(board, currentStone)
),
Stone.WHITE to listOf()
)
override fun isForbidden(location: Location): Boolean {
return forbiddenRulesByStone[currentStone]?.any{
it.isForbidden(location)
}?: false
}
}
stone 을 key, rules 를 value 로 하는 Map을 만든다!
rules List 만 업데이트 해주면 쉽게 새로운 금수룰을 변경하거나 삭제할 수 있다!
그럴리 없겠지만 혹시나 빨간색 돌이 생긴다면 Map 의 원소를 추가해주면 된다~
'우아한테크코스' 카테고리의 다른 글
[안드로이드] MVP 패턴을 MVVM 패턴으로 리팩터링하기 (0) | 2023.07.09 |
---|---|
Presenter 테스트 작성하기 (안드로이드 MVP) : [우아한테크코스 5기 AN_베르] (0) | 2023.06.23 |
블랙잭 상태 패턴 구현 : [우아한테크코스 5기 AN_베르] (0) | 2023.04.10 |
로또 미션 피드백 : [우아한테크코스 5기 AN_베르] (0) | 2023.02.27 |
TDD : [우아한테크코스 5기 AN_베르] (0) | 2023.02.15 |