본문 바로가기
디자인패턴/행위

[디자인패턴] 커맨드 패턴 ... 정리 필요

by se0nghyun2 2023. 4. 18.
더보기

행위패턴 : 객체 간 더 나은 상호작용, 책임 분배 방법 제공하는 패턴

커맨드 = 명령?

 

커맨드 패턴

하나의 요청을 하나의 객체로 캡슐화하여 요청을 파라미터러처럼 사용할 수 있게끔 해주는 패턴

 

 

구조

  • 사용자

명령을 지시하는 객체

 

  • 인보커(호출자)

- 명령을 받아 수신자에게 명령을 전달

- 해당 클래스 내엔 커맨드 참조를 위한 필드가 선언 가능

- 요청을 수신자에게 직접 보내는 것이 아닌 커맨드를 동작

- 커맨드 객체를 참조할 책임이 없으며 일반적으로 생성자를 통해 미리 생성된 커맨드를 받는다.

 

  • 커맨드

- 명령메소드가 담긴 인터페이스

- 자체적 수행 불가

- 비즈니스 논리 객체에게 전달

- 수신 객체에서 메서드를 실행하는데 필요한 매개변수들은 구상 커맨드에 필드로 선언

- 생성자를 통해서만 이러한 필드들 초기화 허용함으로 커맨드 객체 불변으로 만들 수 있다.

- 대부분의 커맨드들은 요청이 수신자에게 전달되는 방법만 처리한다.

 

  • 수신자

- 일부 비즈니스 로직 포함

- 실제 작업 수행

- 구체적인 명령을 실행하는 객체

 


에디터 앱을 만들고 있다고 생각해보자.

복사, 저장, 잘라내기, 삭제 등의 여러 기능들이 있을 것이다.

그리고 "버튼"으로 여러 기능들을 수행할 수 있다!!

 

그래서 상위 버튼 클래스(또는 인터페이스)를 두고 복사,저장,잘라내기 버튼 등을 구현하였다.

<여러 버튼 구현 당시 생각> 

"여기서 바뀌지 않는 개념은 버튼인거고, 기능만 다른 여러 버튼들을 생성하자" 라고 생각하고 구현하였다.....

아래와 같은 구조를 지닌다.

 

 

그런데 !!!!!!     실제 에디터 기능은 버튼뿐만이 아니라 "단축키"를 통해서도 동일한 기능을 수행할 수 있다.

그러면 현재 저장버튼에 구현된 코드들이 동일하게 "저장 단축키클래스"의 메소드 내에 존재하게 될 것이다.

동일한 코드가 여러 곳에 존재하는 것이다....

 

 

이 땐 일반화하는 관점을 달리 해야 할 것으로 보인다.

<관점 변경 후 생각>

위의 경우 바뀌지 않는 것은 버튼이 아닌 기능인거고,

그러면 해당 기능을 수행할 수 있는 객체들인 버튼, 단축키 등을 통해  생성해보는 게 나을 것 같다.

위와 같은 경우는 사물(버튼)이 아니라 행위,기능(복사,잘라내기..)에 대해서 일반화를 생각하면 된다. 

 

다시 말해 저장, 잘라내기, 복사라는 행위는 1.버튼 2.단축키 3. 메뉴툴바 등을 통해서 수행될 수 있으며

아래와 같이 기능을 재사용할 수 있게 된다.

 

언제 사용하나?

여러 액션(버튼 클릭, 단축키) 에서도 동일한 이벤트(복사,저장 등)가 필요한 경우 사용되면 된다.

(어떻게 더 알아듣기 쉽게 바꾸지.,,,,.)

 

전략패턴과 차이점

커맨드에서 요청 처리에 필요한 파라미터들을 멤버변수로 선언하는 반면 전략패턴은 받지 않는다.

이 부분은 아직 정리 안댐..알듯말듯

참고!! https://tecoble.techcourse.co.kr/post/2021-10-04-strategy-command-pattern/


구현한 코드

interface Command{
    void execute();
}

class SaveCommand implements Command{
    @Override
    public void execute() {
        System.out.println("저장 실행");
    }
}

class CutCommand implements Command{
    
    @Override
    public void execute() {
        System.out.println("잘라내기 실행");
    }
}
class CopyCommand implements Command{
    Editor editor;
    String addString;

    CopyCommand(Editor editor, String addString){
        this.editor = editor;
        this.addString =addString;
    }

    @Override
    public void execute() {
        System.out.println("복사 로직 실행");
        editor.add(this.addString);
    }
}

class  Editor{
    StringBuilder text = new StringBuilder();

    void add(String addText){
        this.text.append(addText);
    }
}

class Button{
    Command command;

    Button(Command command){
        setCommand(command);
    }

    void setCommand(Command command){
        this.command = command;
    }

    void click(){
        command.execute();
    }
}

 

위의 구조에선

Button,ShortCut => Invoker(인보커)

CopyCommand, SaveCommand 등 => Command

CopyCommand 내부 멤버변수 Editor => Receiver(수신자)

로 생각하면 된다.

 

 


참고

https://tecoble.techcourse.co.kr/post/2021-10-04-strategy-command-pattern/

[JAVA 디자인패턴] Command pattern(커맨드 패턴) (tistory.com)