코딩/교육
[1227-2] 옵저버 패턴
hoon222y
2018. 12. 27. 20:48
옵저버 패턴 : 객체의 상태 변화를 관찰하고 이를 처리하기 위한 디자인 패턴이다. 이벤트가 발생될 객체에 옵저버 객체들을 등록하고, 상태변화가 있을때마다 메서드 등을 통해 객체가 등록된 옵저버들의 메서드를 호출하여 옵저버에게 알려준다 .
옵저버 패턴 : 객체의 상태 변화를 관찰하려는 관찰자들, 즉 옵저버들의 목록을 객체에 등록하여 상태변화가 있을 때마다 메서드 등을 통해 객체가 직접 목록의 각 옵저버들에게 통지하도록 하는 디자인 패턴
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | package Observer; import java.util.ArrayList; public class main { public static void main(String[] args) { Button closeBtn = new Button("닫기"); //버튼이 눌릴 경우, 내부적으로 아래의 메서드가 호출됩니다. //이처럼 누군가에 의해 호출당하는 개념을 콜백(callback)이라고 한다. closeBtn.click(); } } class Button{ private String label; public Button(String label) {this.label = label;} public void click() { //이 메서드 안에서 버튼이 클릭되었을 때의 이벤트를 처리하면 됩니다. System.out.println("다이얼로그가 닫힙니다."); } } public class main { public static void main(String[] args) { CloseButton closeBtn = new CloseButton("닫기"); closeBtn.click(); } } class Button{ protected String label; public Button(String label) {this.label = label;} // 현재 버튼은 이미 라이브러리로 구현되어 있어 수정될 수 없으므로 // 사용자는 버튼의 콜백 메서드에 처리 코드를 구현할 수 없습니다. public void click() {} } //이제 버튼에 대한 콜백을 구현하기 위해 기존 버튼을 상속하여 구현한다. class CloseButton extends Button{ public CloseButton(String label) {super(label);} public void click() { System.out.println("다이얼로그가 닫힙니다."); } } | cs |
콜백(callback) : 누군가에 의해 호출당하는 개념
하지만 이 코드는 이벤트 처리를 위해 상속을 사용하였다. 버튼의 경우, 이미 라이브러리 안에 있으므로 사용자가 이를 직접 사용할 수 없기 때문이다. 따라서 이를 해결하기 위해 이벤트 버튼이 직접 처리하는것이 아니라 옵저버를 통해 외부에 알리는 방식으로 해결할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | package Observer; import java.util.ArrayList; public class main { public static void main(String[] args) { Button closeBtn = new Button("닫기"); closeBtn.setOnClickListener(new OnClickListener() { public void onClick() { System.out.println("윈도우가 닫힙니다."); } }); closeBtn.click(); } } // 외부에 알리기 위해 추상 클래스와 인터페이스를 사용할수 있는데 이 때, 인터페이스 기반으로 // 구현하는것이 좋습니다. interface OnClickListener{ public void onClick(); } // 만약 이벤트를 처리하는 핸들러가 재사용할 것이라면 아래와 같이 클래스로 // 구현해도 됩니다. 하지만 특정 이벤트처리만 수행할 것이라면 아래와 같이 클래스를 // 설계하는것은 일종의 낭비이다. class OnClickListenerImpl implements OnClickListener{ @Override public void onClick() { } } class Button { protected String label; private OnClickListener listener = null; // private ArrayList<OnClickListener> list = new ArrayList<>(); // 이렇게 하면 여러개 객체에 대해서 통제가능 / 내부적으로 객체를 여러개 public Button(String label) {this.label = label;} public void setOnClickListener(OnClickListener l) { listener=l; //list.add(l); } public void click() { // 이제 이벤트가 발생하면 외부에 알리도록 합니다. if(listener != null)listener.onClick(); } } | cs |