MVC vs Observer Pattern (MVC 패턴과 옵저버 패턴 차이점)
MVC
- Model: It includes all the data and its related logic
- View: Present data to the user or handles user interaction
- Controller: An interface between Model and View components
View
A View is that part of the application that represents the presentation of data.
Views are created by the data collected from the model data. A view requests the model to give information so that it resents the output presentation to the user.
The view also represents the data from chats, diagrams, and table. For example, any customer view will include all the UI components like text boxes, drop downs, etc.
View는 데이터의 표시를 나타내는 응용 프로그램의 일부입니다.
View는 모형 데이터에서 수집된 데이터에 의해 만들어집니다. 뷰는 모델이 출력 프레젠테이션을 사용자에게 다시 표시하도록 정보를 제공하도록 요청합니다.
View는 대화, 다이어그램 및 테이블의 데이터도 나타냅니다. 예를 들어, 모든 고객 보기에는 텍스트 상자, 드롭다운 등과 같은 모든 UI 구성 요소가 포함됩니다.
Controller
The Controller is that part of the application that handles the user interaction. The controller interprets the mouse and keyboard inputs from the user, informing model and the view to change as appropriate.
A Controller send's commands to the model to update its state(E.g., Saving a specific document). The controller also sends commands to its associated view to change the view's presentation (For example scrolling a particular document).
Controller는 사용자 상호 작용을 처리하는 응용 프로그램의 일부입니다. Controller는 사용자가 입력한 마우스와 키보드 입력을 해석하여 모델 및 뷰가 적절하게 변경되도록 알립니다.
Controller가 모델 상태를 업데이트하도록 명령을 전송합니다(예: 특정 문서 저장). 또한 Controller는 View의 프리젠테이션을 변경하기 위해 연결된 뷰로 명령을 전송합니다(예: 특정 문서 스크롤).
Model
The model component stores data and its related logic. It represents data that is being transferred between controller components or any other related business logic. For example, a Controller object will retrieve the customer info from the database. It manipulates data and send back to the database or use it to render the same data.
It responds to the request from the views and also responds to instructions from the controller to update itself. It is also the lowest level of the pattern which is responsible for maintaining data.
Model 구성 요소는 데이터와 관련 로직을 저장합니다. Controller 구성 요소 간에 전송되는 데이터 또는 기타 관련 비즈니스 로직을 나타냅니다. 예를 들어 Controller 개체는 데이터베이스에서 고객 정보를 검색합니다. 데이터를 조작하여 데이터베이스로 다시 전송하거나 동일한 데이터를 렌더링하는 데 사용합니다.
View의 요청에 응답하고 컨트롤러의 업데이트 지시에도 응답합니다. 데이터 유지관리를 담당하는 패턴의 가장 낮은 레벨이기도 합니다.
MVC Examples
Let's see Model View Controller from daily life:
Example 1:
- Let's assume you go to a restaurant. You will not go to the kitchen and prepare food which you can surely do at your home. Instead, you just go there and wait for the waiter to come on.
- Now the waiter comes to you, and you just order the food. The waiter doesn't know who you are and what you want he just written down the detail of your food order.
- Then, the waiter moves to the kitchen. In the kitchen waiter not prepare your food.
- The cook prepares your food. The waiter is given your order to him along with your table number.
- Cook then prepared food for you. He uses ingredients to cooks the food. Let's assume that your order a vegetable sandwich. Then he needs bread, tomato, potato, capsicum, onion, bit, cheese, etc. which he sources from the refrigerator.
- Cook final hand over the food to the waiter. Now it is the job of the waiter to moves this food outside the kitchen.
- Now waiter knows which food you have ordered and how they are served.
View = You
Waiter = Controller
Cook = Model
Refrigerator = Data
Observer Pattern
이 기사에서는 Observer 패턴에 대해 설명하고 몇 가지 Java 구현 대안을 살펴보겠습니다.
Observer Pattern 는 behavior architecture pattern입니다. Observable와 관찰자 간의 통신을 지정합니다. 관찰 가능한 개체는 관찰자에게 상태 변화에 대해 알리는 개체입니다.
예를 들어, 뉴스 통신사는 뉴스를 수신할 때 채널에 알릴 수 있다. 뉴스 수신은 통신사의 상태를 변화시키는 것이고, 그것은 채널을 통보하게 한다.
Observer is a behavioral design pattern. It specifies communication between objects: observable and observers. An observable is an object which notifies observers about the changes in its state.
For example, a news agency can notify channels when it receives news. Receiving news is what changes the state of the news agency, and it causes the channels to be notified.
Let's see how we can implement it ourselves.
우리가 그것을 어떻게 구현할 수 있는지 봅시다.
Example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public class NewsAgency {
private String news;
private List<Channel> channels = new ArrayList<>();
public void addObserver(Channel channel) {
this.channels.add(channel);
}
public void removeObserver(Channel channel) {
this.channels.remove(channel);
}
public void setNews(String news) {
this.news = news;
for (Channel channel : this.channels) {
channel.update(this.news);
}
}
}
|
cs |
NewsAgency is an observable, and when news gets updated, the state of NewsAgency changes. When the change happens, NewsAgency notifies the observers about this fact by calling their update() method.
To be able to do that, the observable object needs to keep references to the observers, and in our case, it's the channels variable.
Let's now see how the observer, the Channel class, can look like. It should have the update() method which is invoked when the state of NewsAgency changes:
뉴스 에이전시는 관찰 가능하며, 뉴스가 업데이트되면 뉴스 에이전시의 상태가 변경됩니다. 변경 사항이 발생하면 News Agency는 관찰자에게 update() method을 호출하여 이 사실을 알립니다.
이를 위해 관측 가능한 개체는 관찰자에 대한 참조를 유지해야 하며, 우리의 경우 채널 변수입니다.
이제 관찰자, 채널 클래스가 어떻게 생겼는지 보겠습니다. 뉴스 에이전시의 상태가 변경될 때 호출되는 update() method이 있어야 합니다.
1
2
3
4
5
6
7
8
|
public class NewsChannel implements Channel {
private String news;
@Override
public void update(Object news) {
this.setNews((String) news);
}
}
|
cs |
The Channel interface has only one method:
1
2
3
|
public interface Channel {
public void update(Object o);
}
|
cs |
Now, if we add an instance of NewsChannel to the list of observers, and change the state of NewsAgency, the instance of NewsChannel will be updated:
이제 뉴스 채널의 인스턴스를 관찰자 목록에 추가하고 뉴스 에이전시의 상태를 변경하면 뉴스 채널의 인스턴스가 업데이트됩니다.
1
2
3
4
5
6
|
NewsAgency observable = new NewsAgency();
NewsChannel observer = new NewsChannel();
observable.addObserver(observer);
observable.setNews("news");
assertEquals(observer.getNews(), "news");
|
cs |
There's a predefined Observer interface in Java core libraries, which makes implementing the observer pattern even simpler. Let's look at it.
Java 핵심 라이브러리에는 미리 정의된 관찰자 인터페이스가 있어 관찰자 패턴을 훨씬 더 간단하게 구현할 수 있습니다. 한 번 봅시다.
3. Implementation With Observer
The java.util.Observer interface defines the update() method, so there's no need to define it ourselves as we did in the previous section.
Let's see how we can use it in our implementation:
java.util.Observer interface는 update() method을 정의하므로 이전 섹션에서와 같이 직접 정의할 필요가 없습니다.
이를 구현에 사용할 수 있는 방법을 살펴보겠습니다.
1
2
3
4
5
6
7
8
9
|
public class ONewsChannel implements Observer {
private String news;
@Override
public void update(Observable o, Object news) {
this.setNews((String) news);
}
}
|
cs |
Here, the second argument comes from Observable as we'll see below.
여기서 두 번째 인수는 아래와 같이 Observable에서 나옵니다.
To define the observable, we need to extend Java's Observable class:
Observable을 정의하려면 Java의 Observable class를 확장해야 합니다.
1
2
3
4
5
6
7
8
9
|
public class ONewsAgency extends Observable {
private String news;
public void setNews(String news) {
this.news = news;
setChanged();
notifyObservers(news);
}
}
|
cs |
Note that we don't need to call the observer's update() method directly. We just call setChanged() and notifyObservers(), and the Observable class is doing the rest for us.
Also, it contains a list of observers and exposes methods to maintain that list – addObserver() and deleteObserver().
To test the result, we just need to add the observer to this list and to set the news:
Observer의 update() method을 직접 호출할 필요는 없습니다. 우리는 단지 setChanged()를 불러서 Observers()에게 통지할 뿐이고, 나머지는 Observable class가 대신 하고 있습니다.
또한 a list of observers을 포함하고 이 목록을 유지하기 위한 방법을 표시합니다. addObserver() 및 deleteObserver().
결과를 테스트하려면 Observer를 이 목록에 추가하고 뉴스를 설정하면 됩니다.
1
2
3
4
5
6
|
ONewsAgency observable = new ONewsAgency();
ONewsChannel observer = new ONewsChannel();
observable.addObserver(observer);
observable.setNews("news");
assertEquals(observer.getNews(), "news");
|
cs |
Observer interface isn't perfect and is deprecated since Java 9. One of its cons is that Observable isn't an interface but a class, that's why subclasses can't be used as observables.
Also, a developer could override some of the Observable‘s synchronized methods and disrupt their thread-safety.
Let's look at the ProperyChangeListener interface, which is recommended instead of using Observer.
Observer interface는 완벽하지 않으며 Java 9 이후 더 이상 사용되지 않습니다. 그 중 하나는 Observable이 인터페이스가 아니라 클래스라는 점입니다. 그래서 하위 클래스는 관찰 가능한 클래스로 사용할 수 없습니다.
또한 개발자는 Observable의 동기화된 방법 중 일부를 재정의하여 스레드 안전을 방해할 수 있다.
관찰자 대신 PropertyChangeListener 인터페이스를 살펴보겠습니다.
4. Implementation With PropertyChangeListener
In this implementation, an observable must keep a reference to the PropertyChangeSupport instance. It helps to send the notifications to observers when a property of the class is changed.
이 구현에서 관찰 가능한 사용자는 PropertyChangeSupport instance에 대한 참조를 유지해야 합니다. 클래스의 속성이 변경될 때 관찰자에게 알림을 보내는 데 도움이 됩니다.
Let's define the observable:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
public class PCLNewsAgency {
private String news;
private PropertyChangeSupport support;
public PCLNewsAgency() {
support = new PropertyChangeSupport(this);
}
public void addPropertyChangeListener(PropertyChangeListener pcl) {
support.addPropertyChangeListener(pcl);
}
public void removePropertyChangeListener(PropertyChangeListener pcl) {
support.removePropertyChangeListener(pcl);
}
public void setNews(String value) {
support.firePropertyChange("news", this.news, value);
this.news = value;
}
}
|
cs |
Using this support, we can add and remove observers, and notify them when the state of the observable changes:
이 지원을 사용하여 observers를 추가 및 제거하고 관찰 가능한 상태가 변경될 때 알릴 수 있습니다.
1
|
support.firePropertyChange("news", this.news, value);
|
cs |
Here, the first argument is the name of the observed property. The second and the third arguments are its old and new value accordingly.
Observers should implement PropertyChangeListener:
여기서 첫 번째 인수는 관찰된 속성의 이름입니다. 두 번째와 세 번째 주장은 그에 따른 오래된 가치와 새로운 가치이다.
Observers는 PropertyChangeListener를 구현해야 합니다.
1
2
3
4
5
6
7
8
|
public class PCLNewsChannel implements PropertyChangeListener {
private String news;
public void propertyChange(PropertyChangeEvent evt) {
this.setNews((String) evt.getNewValue());
}
}
|
cs |
Due to the PropertyChangeSupport class which is doing the wiring for us, we can restore the new property value from the event.
Let's test the implementation to make sure that it also works:
우리를 위해 배선을 하는 PropertyChangeSupport 클래스 때문에 우리는 이벤트에서 새로운 속성 값을 복원할 수 있습니다.
구현을 테스트하여 다음과 같이 작동하는지 확인하십시오.
1
2
3
4
5
6
7
|
PCLNewsAgency observable = new PCLNewsAgency();
PCLNewsChannel observer = new PCLNewsChannel();
observable.addPropertyChangeListener(observer);
observable.setNews("news");
assertEquals(observer.getNews(), "news");
|
cs |
5. Conclusion
In this article, we've examined two ways to implement the Observer design pattern in Java, with the PropertyChangeListener approach being preferred.
'공부 > Object-Oriented Design Pattern' 카테고리의 다른 글
Visitor Pattern (방문자 패턴)이란 (0) | 2021.05.11 |
---|---|
Factory Method Pattern (팩토리 메소드 패턴) (0) | 2021.05.07 |
[Proxy Pattern] 프록시 패턴이란 (0) | 2021.04.15 |
[OODP] Singleton Pattern (싱글톤 패턴)이란 (0) | 2021.04.04 |
Java Socket 메시지 주고받기 (0) | 2021.04.03 |
댓글