Duck
public abstract class Duck {
public void quack() {
System.out.println("꽥꽥");
}
}
Duck 클래스를 상속받는 3개의 클래스를 확인해 보자.
public class Duck1 extends Duck {
}
public class Duck2 extends Duck {
@Override
public void quack() {
System.out.println("-무음-");
}
}
public class Duck3 extends Duck {
@Override
public void quack() {
System.out.println("-무음-");
}
}
무음이었던 2번 오리의 quak 메서드가 변경된다면 어떻게 해야 할까요?
아래와 같이 변경을 할 것입니다.
public class Duck2 extends Duck {
@Override
public void quack() {
System.out.println("삑");
}
}
문제점
어떤 문제점이 보이나요?
1. OCP 위배
- 변경에는 닫혀있고, 확장에만 열려있어야 하는데 직접적으로 변경을 하고 있기 때문에 OCP 위배라고 볼 수 있습니다.
2. 서브클래스에서 코드가 중복된다.
- 2번 3번 오리는 둘다 무음이었음에도 불구하고, 중복되는 코드를 매번 작성해주고 있다.
3. Super 클래스의 메서드를 변경하면 서브클래스가 원치 않는 영향을 받을 수 있다.
해결 - Strategy 패턴 적용
달라지는 부분과 달라지지 않는 부분을 찾아내고, 분리한다.
이 경우 달라지는 부분은 quack 메서드이다.
적절하게 추출하여 interface로 만들어보자.
동작에 대한 행위를 따로 추출해 냅니다.
public interface QuackBehavior {
public void quack();
}
행동을 구현한 구현체를 만들어 줍니다.
3가지 종류의 Quack 메서드를 구현해줍니다.
첫번째 '꽥'
public class Quack implements QuackBehavior {
@Override
public void quack() {
System.out.println("꽥");
}
}
두번째 '꽥'
public class MuteQuack implements QuackBehavior {
@Override
public void quack() {
System.out.println("-무음-");
}
}
세번째 '꽥'
public class Squeak implements QuackBehavior {
@Override
public void quack() {
System.out.println("삑");
}
}
만들어 놓은 '꽥' 메서드를 적용해봅시다.
'꽥' 행동을 정의해 놓은 QuackBehavior을 필드 변수로 받습니다.
QuackBehavior의 quack 메서드를 performQuack 의 메서드를 완성합니다.
public abstract class Duck {
QuackBehavior quackBehavior;
public void performQuack() {
quackBehavior.quack();
}
public QuackBehavior getQuackBehavior() {
return quackBehavior;
}
public void setQuackBehavior(QuackBehavior quackBehavior) {
this.quackBehavior = quackBehavior;
}
}
quackBehavior의 구현체가 존재하지 않는 상황입니다.
생성자에서 구현체를 정의해주도록 합시다.
public class Duck1 extends Duck {
public Duck1() {
quackBehavior = new Quack();
}
}
2번 오리
public class Duck2 extends Duck {
public Duck2() {
quackBehavior = new MuteQuack();
}
}
3번 오리
public class Duck3 extends Duck {
public Duck3() {
quackBehavior = new MuteQuack();
}
}
setter를 이용하여 실행시에 동작을 바꿀 수 있는 형태를 취하고 있습니다.
public class MiniDuckSimulator {
public static void main(String[] args) {
Duck duck = new Duck2();
duck.performQuack();
duck.setQuackBehavior(new Quack());
duck.performQuack();
}
}
결과를 확인해 볼까요?
'공부방 > JAVA' 카테고리의 다른 글
Consumer (0) | 2022.07.28 |
---|---|
디자인 패턴 - 옵저버 패턴 (0) | 2022.07.14 |
mysql - 2일차 (0) | 2022.07.08 |
mysql (0) | 2022.07.07 |
Map, Hash table (0) | 2022.06.19 |