- 정의
- 사용 이유
- 구현
A
객체에서 B
객체의 메서드를 실행하기 위해서는 B
를 참조하고 있어야 한다. (의존성 발생) => 커맨드 패턴을 통해 의존성 제거문서 편집기에 대한 예제를 살펴보자
public class NonTextEditor {
private Copier copier;
public NonTextEditor(Copier copier) {
this.copier = copier;
}
public void copy() {
copier.copy();
}
}
public class Copier {
public void copy(){
System.out.println("복사");
}
}
public class User {
public static void main(String[] args) {
Copier copier = new Copier();
NonTextEditor nonTextEditor = new NonTextEditor(copier);
nonTextEditor.copy();
}
}
print >>>
복사
현재 문서 편집기의 기능은 복사
만 존재하지만 붙혀넣기
와 자르기
와 같이 새로운 기능을 추가할 때, 코드 변경은 불가피하다.
public class NonTextEditor {
private Copier copier;
private Paster paster;
private Cutter cutter;
private Skill skill;
public NonTextEditor(Copier copier, Paster paster, Cutter cutter) {
this.copier = copier;
this.paster = paster;
this.cutter = cutter;
}
public void setSkill(Skill skill) {
this.skill = skill;
}
public void useEditor() {
switch (this.skill) {
case COPIER:
copier.copy();
break;
case PASTER:
paster.paste();
break;
case CUTTER:
cutter.cut();
break;
}
}
}
public class Copier {
public void copy(){
System.out.println("복사");
}
}
public class Paster {
public void paste() {
System.out.println("붙혀넣기");
}
}
public class Cutter {
public void cut() {
System.out.println("잘라내기");
}
}
//enum
public enum Skill {
COPIER, PASTER, CUTTER
}
public class User {
public static void main(String[] args) {
Copier copier = new Copier();
Paster paster = new Paster();
Cutter cutter = new Cutter();
NonTextEditor nonTextEditor = new NonTextEditor(copier, paster, cutter);
nonTextEditor.setSkill(Skill.COPIER);
nonTextEditor.useEditor();
nonTextEditor.setSkill(Skill.PASTER);
nonTextEditor.useEditor();
nonTextEditor.setSkill(Skill.CUTTER);
nonTextEditor.useEditor();
}
}
기능이 많아질수록, 객체에 대한 의존성이 많아진다.
useEditor()
의 분기가 증가한다.
OCP (Open-Closed Principle) 위반
각 기능을 클래스로 생성하여 인터페이스로 캡슐화한다.
기능을 사용하는 클래스(TextEditor
)에서 인터페이스의 메서드를 호출한다.
public interface EditorCommand {
void useEditor();
}
public class CopyCommand implements EditorCommand {
private Copier copier;
public CopyCommand(Copier copier) {
this.copier = copier;
}
@Override
public void useEditor() {
copier.copy();
}
}
////
public class PasteCommand implements EditorCommand {
private Paster paster;
public PasteCommand(Paster paster) {
this.paster = paster;
}
@Override
public void useEditor() {
paster.paste();
}
}
////
public class CutCommand implements EditorCommand {
private Cutter cutter;
public CutCommand(Cutter cutter) {
this.cutter = cutter;
}
@Override
public void useEditor() {
cutter.cut();
}
}
public class TextEditor {
private EditorCommand editorCommand;
public void setEditorCommand(EditorCommand editorCommand) {
this.editorCommand = editorCommand;
}
public void useEditor() {
editorCommand.useEditor();
}
}
문서편집기
에 EditorCommand
에 대한 의존성만 존재.XXX
와 XXXCommand
를 추가하면 되기 때문에 OCP에 위배되지 않는다.non
과 adapt
을 비교했을 때, 클래스의 수가 많아진 것을 볼 수 있다.Git : https://github.com/JinMinChoi/Design-Pattern/tree/master/src/command