본문 바로가기

공부방/JAVA

디자인 패턴 - strategy pattern

 

 

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