전략패턴 2

연어는결국강으로·2022년 12월 21일
0

GoF 디자인 패턴

목록 보기
17/18

메타코딩 디자인패턴 강의가 나와서 디자인패턴을 복습하고 있다.
대부분의 강의가 그렇듯 메타코딩에서도 전략패턴을 첫 번째 패턴으로 두었다. 아마도 가장 기본이 되는 패턴이기 때문이겠지?

전략패턴은 SOLID원칙중 D(DIP)를 충실히 따르는 것이다.

프로그래머는 “추상화에 의존해야지, 구체화에 의존하면 안된다.”


먼저 시나리오는 문지기가 있고, 이 문지기가 동물들을 쫓아내는 프로그램을 짜는 스토리이다.

  • 아래 코드는 그냥 쥐라는 객체를 구현해 놓은것으로 getName으로 이름을 반환받을 수 있는 메소드를 포함하고 있다.
public class Mouse {
	private String name = "쥐";

	public String getName() {
		return name;
	}

}
  • 아래는 문지기로 쥐를 쫓아내는 함수를 가지고 있다.
public class DoorMan {
	
	public void 쫓아내(Mouse m) {
		System.out.println(m.getName() + " 쫓아내");
	}

}
  • 마지막으로 이것들을 실행시키는 App 클래스이다.
public class App {

	public static void main(String[] args) {
		Mouse m = new Mouse();
		DoorMan dm = new DoorMan();
		dm.쫓아내(m);
	}
}

일단은 이렇게 하면 프로그램은 잘 돌아간다. 그러나 프로그램을 쥐만 넣을게 아니라 고양이나 호랑이나 늑대같은 다른 동물도 쫓아내는 함수를 구현하려고 하면, 즉 프로그램을 확장하려고 하면 쫓아내를 오버로딩하는 함수를 일일히 구현해야 되는 번거로움이 있다.

이것은 SOLID 원칙중 D를 다시 생각해보게 한다. DoorMan은 Mouse라는 굉장히 구체적인 객체에 의존하고 있지않은가? 이것을 타개하고자 전략패턴을 사용한다.


  • 동물이라는 추상 클래스를 구현한다.
  • 이 추상 클래스는 getName이라는 함수 역시 추상화시켜 놓았다.
public abstract class Animal {
	public abstract String getName();

}
  • 그리고 이것을 쥐나 다른 동물 클래스를 만들때마다 상속시킨다.
// 쥐 클래스
public class Mouse extends Animal {
	private String name = "쥐";

	public String getName() {
		return name;
	}

}
// 고양이 클래스
public class Cat extends Animal{
	
	private String name = "고양이";

	@Override
	public String getName() {
		return name;
	}

}
  • 이렇게 하고 문지기는 쫓아내 함수의 input으로 Animal객체를 넣어주면 doorman은 별도의 메소드를 구현하지 않고서 모든 Animal을 상속받는 클래스에 대하여 쫓아내 매소드를 사용할 수 있다.
public class DoorMan {
	
	public void 쫓아내(Animal m) {
		System.out.println(m.getName() + " 쫓아내");
	}

}
public class App {

	public static void main(String[] args) {
		Mouse m = new Mouse();
		Cat c = new Cat();
		DoorMan dm = new DoorMan();
		dm.쫓아내(m);
		dm.쫓아내(c);
	}
}

정리하자면 전략패턴은 '추상화에 의존하라' 를 구체적으로 보여준 패턴이라고 생각한다. 의존성을 주입할 때 너무 구체적인 존재에 의존하지는 않는지 항상 생각해야겠다.

0개의 댓글