메타코딩 디자인패턴 강의가 나와서 디자인패턴을 복습하고 있다.
대부분의 강의가 그렇듯 메타코딩에서도 전략패턴을 첫 번째 패턴으로 두었다. 아마도 가장 기본이 되는 패턴이기 때문이겠지?
전략패턴은 SOLID원칙중 D(DIP)를 충실히 따르는 것이다.
프로그래머는 “추상화에 의존해야지, 구체화에 의존하면 안된다.”
먼저 시나리오는 문지기가 있고, 이 문지기가 동물들을 쫓아내는 프로그램을 짜는 스토리이다.
public class Mouse {
private String name = "쥐";
public String getName() {
return name;
}
}
public class DoorMan {
public void 쫓아내(Mouse m) {
System.out.println(m.getName() + " 쫓아내");
}
}
public class App {
public static void main(String[] args) {
Mouse m = new Mouse();
DoorMan dm = new DoorMan();
dm.쫓아내(m);
}
}
일단은 이렇게 하면 프로그램은 잘 돌아간다. 그러나 프로그램을 쥐만 넣을게 아니라 고양이나 호랑이나 늑대같은 다른 동물도 쫓아내는 함수를 구현하려고 하면, 즉 프로그램을 확장하려고 하면 쫓아내를 오버로딩하는 함수를 일일히 구현해야 되는 번거로움이 있다.
이것은 SOLID 원칙중 D를 다시 생각해보게 한다. DoorMan은 Mouse라는 굉장히 구체적인 객체에 의존하고 있지않은가? 이것을 타개하고자 전략패턴을 사용한다.
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;
}
}
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);
}
}
정리하자면 전략패턴은 '추상화에 의존하라' 를 구체적으로 보여준 패턴이라고 생각한다. 의존성을 주입할 때 너무 구체적인 존재에 의존하지는 않는지 항상 생각해야겠다.