프로그래밍을 하면서 디자인패턴에 관한 지식이 없는 상태로 개발을 하다보니, 굉장히 비효율적으로 소스를 작성하고 있는 나 자신을 많이 보게 된다. 처음에 원하는 기능을 구현하는데까지는 문제가 없지만, 이후 수정사항이 발생할 경우 하나의 기능을 고치는 상황에도 많은 시간이 들고 예기치않은 오류들이 발생하더라.
효율적으로 설계를 하기 위해 패턴에 관한 책을 읽기 시작했다. 앞으로 한 패턴씩 공부하고 공부한 내용을 복습할 겸 간단하게 정리해서 올려보겠다.
1. 전략 패턴 정의
간단하게 말해 어떤 동작을 하는 로직을 정의하고 이것들을 하나로 묶어서(캡슐화) 관리하도록 하는 패턴이다. 로직을 사용하는 객체들은 자기의 입맛에 맞게 로직을 효율적으로 수정할 수 있다. 새로운 로직을 추가하거나 변경할 때 객체의 종류 수 만큼 반복하지 않고, 단 한번으로 반영할 수 있다.
2. 예시
슈팅게임을 만드려고 한다.
유닛의 종류에는 전투기, 헬리콥터가 있고, 각각 미사일을 발사할 수 있다.
전투기는 미사일이 직선으로 나가지만 헬리콥터는 유도탄 처럼 나간다.
필살기로 폭탄이 있는데 전투기는 있지만, 헬리콥터는 없다.
이 예시를 Strategy Pattern 을 적용하여 설계를 해보자. 여기서의 핵심은 로직을 정의하는 행동에도 객체를 선언한다는 것이다. 그리고 상속보다는 구성(Composition) 을 이용한다! 상속만으로 진행하게 되면 무분별한 소스 중복이 일어날 수 있기 때문이다. Interface와 로직의 class와의 관계를 composition 하고 유닛에서 상황에 맞는 로직을 쓰게끔 유도한다.
전체 설계를하면 위와같이 된다. 일단 로직으로는 미사일쏘는 부분과 폭탄을쏘는 부분 크게 두가지므로 각각 캡슐화한다. 인터페이스로 ShootAction, BombAction 을 선언하여 형태를 만든다. 그 다음 미사일 쏘는 부분에서 직선과 유도탄 형식 두가지의 로직이 나오는데 이것들을 전부 ShootAction 인터페이스로 연결한다.
다음에 새로운 미사일의 형태, 예를 들면 Y 자로 퍼지는 미사일을 추가하고 싶을때 ShootAction 인터페이스에 연결한 새로운 Class를 생성하여 로직을 작성하면된다.
폭탄도 마찬가지. BombAction 인터페이스를 만들어놓고 SpreadBomb와 NoBomb를 만든다. NoBomb는 폭탄이 없다는 뜻의 클래스이다. bomb() 내부에는 아무 내용도 존재하지않는다.
이렇게 다양한 로직들을 적용하기 위해 유닛부분을 손봐야한다. 유닛종류에는 전투기, 헬리콥터 두 종류인데 이 상위 추상클래스인 Unit 을 선언한다. Unit에는 display 와 같이 유닛을 그리는 공통적인 메서드가 들어있고, 각각 유닛에 맞는 미사일과 폭탄을 선언하기 위해 인터페이스 형식의 variable 을 선언한다.
실질적으로 Unit 클래스를 상속받은 전투기(Fighter) 클래스와 헬리콥터(Helicopter) 클래스에서는 생성자에 각각에 맞는 미사일과 폭탄을 정의하면 끝. 소스로 예를 들면,
class Fighter extends Unit {
private ShootAction shootAction;
public Fighter() {
shootAction = new OneWayMissile();
}
}
이렇게 Fighter 클래스의 인터페이스 변수인 shootAction 에 new OneWayMssile 을 대입하고 Fighter.doAttack()
을 호출하게되면 OneWayMissile 에 attack() 부분이 호출될 것이다. 이런 방식으로 관리하면 된다.
3. 정리
- 상속보다는 구성 (Composition) 을 이용
- 로직이 들어가는 “행동” 에도 클래스를 선언할 수 있음, 인터페이스와 연결
- A는 B다 보다는 A에 B가 있다 가 더 좋음
- 장점은 로직을 독립적으로 관리하기 쉬움
'Programming > Design Pattern' 카테고리의 다른 글
디자인패턴 - 옵저버 패턴(Observer Pattern) (6) | 2016.01.25 |
---|
댓글