IT TIP

사람들이 코드에 메시지 / 이벤트 버스를 사용하는 이유는 무엇입니까?

itqueen 2020. 12. 3. 21:34
반응형

사람들이 코드에 메시지 / 이벤트 버스를 사용하는 이유는 무엇입니까?


메시지 / 이벤트 버스에 대해 들어 본 적이 있다고 생각합니다. 시스템의 모든 이벤트가 흐르는 단일 장소입니다. 유사한 아키텍처가 컴퓨터의 마더 보드 및 LAN 네트워크에서 발견됩니다. 와이어 수를 줄이므로 마더 보드 및 네트워크에 적합한 접근 방식이지만 소프트웨어 개발에 적합합니까? 우리는 전자 제품과 같은 제한이 없습니다.

메시지 버스 / 이벤트 버스의 가장 간단한 구현은 다음과 같습니다.

class EventBus {
    void addListener(EventBusListener l}{...}
    void fireEvent(Event e) {...}
}

이벤트 게시는 bus.fireEvent (event)로 이루어지며, 메시지 수신은 bus.addListener (listener)에 의해 활성화됩니다. 이러한 아키텍처는 때때로 소프트웨어 개발에 사용됩니다. 예를 들어 MVP4G는 GWT에 대해 유사한 메시지 버스를 구현합니다.

활성 프로젝트 :

휴면 / 죽은 프로젝트 :

그것은 단지 '전역 적으로'만들어진 인기있는 Observer (Listener) 패턴 일뿐입니다. 시스템의 각 객체는 각 메시지를들을 수 있으며, 나쁘다고 생각합니다. 캡슐화 원칙 (각 객체가 모든 것을 알고 있음)과 단일 책임 원칙 (예 : 일부 객체는 새로운 유형의 메시지를 필요로하며, 이벤트 버스는 예를 들어 새 리스너 클래스 또는 리스너 클래스에 새 메소드를 추가하기 위해 종종 변경되어야합니다.

이러한 이유로 대부분의 소프트웨어에서 Observer 패턴이 이벤트 버스보다 낫다고 생각합니다. 이벤트 버스에 대해 어떻게 생각하십니까? 일반적인 응용 분야에 적합합니까?

편집 : ESB와 같은 '대형'엔터프라이즈 솔루션에 대해 말하는 것이 아닙니다. 유용 할 수 있습니다 (더 많은 ESB가 이벤트 버스보다 훨씬 더 많은 것을 제공합니다). 객체 대 객체 연결을 위해 '일반적인'Java 코드에서 메시지 버스를 사용하는 것의 유용성에 대해 묻고 있습니다. 일부 사람들은 위의 링크를 확인하십시오. 이벤트 버스는 전화 대 전화 통신 또는 컴퓨터 대 컴퓨터 통신에 가장 적합한 솔루션 일 것입니다. 네트워크의 각 텔레폰 (또는 컴퓨터)은 일반적으로 서로 통신 할 수 있고 버스는 전선 수를 줄이기 때문입니다. 그러나 개체는 서로 거의 대화하지 않습니다. 한 개체에 몇 명의 공동 작업자가있을 수 있습니까? 3, 5?


어떤 사람들은 그것이 Facade 패턴 또는 Mediator 패턴 의 구체화이기 때문에 그것을 좋아합니다 . 로깅, 경고, 모니터링, 보안 등과 같은 교차 작업을 중앙 집중화합니다.

어떤 사람들은 종종 Singleton 실패 지점이기 때문에 그것을 좋아하지 않습니다. 모두가 그것에 대해 알아야합니다.


일반 Java 코드에 In Memory Event Bus를 사용할 것을 고려하고 있으며 그 이유는 다음과 같습니다.

시스템의 각 개체는 각 메시지를들을 수 있으며, 나쁘다고 생각합니다. 캡슐화 원칙을 위반합니다 (각 개체는 모든 것을 알고 있음).

이것이 사실인지 확실하지 않습니다. I 클래스는 관찰자 패턴과 유사하게 이벤트 버스에 등록해야합니다. 일단 클래스가 이벤트 버스에 등록되면 적절한 서명과 주석이있는 메서드 만 알림을받습니다. .

및 단일 책임 원칙 (예 : 일부 객체가 새로운 유형의 메시지를 필요로하는 경우, 예를 들어 새로운 리스너 클래스 또는 리스너 클래스에 새 메소드를 추가하기 위해 이벤트 버스를 자주 변경해야 함).

나는 완전히 동의하지 않는다

이벤트 버스는 자주 변경해야합니다.

이벤트 버스는 변경되지 않습니다

동의합니다

add a new Listener class or a new method in the Listener class

이것이 SRP를 어떻게 중단합니까?, Book Entity와 관련된 모든 이벤트를 구독하는 BookEventListener를 가질 수 있으며 예,이 클래스에 메서드를 추가 할 수 있지만 여전히이 클래스는 응집력이 있습니다.

왜 사용할 계획입니까? 내 도메인의 "언제"를 모델링하는 데 도움이됩니다. ....

보통 우리 는 책을 구입 한 "언제" 메일을 보내는 것과 같은 것을 듣습니다.

우리는 적어 간다

book.purchase();
sendEmail()

그런 다음 책을 구입할 때 감사 로그를 추가하라는 메시지가 표시되면 위의 스 니펫으로 이동합니다.

book.purchase();
sendEmail();
**auditBook();**

바로 거기 OCP 위반

나는 선호한다

book.purchase();
EventBus.raiseEvent(bookPurchasedEvent);

그런 다음 필요에 따라 처리기를 계속 추가합니다. 확장을 위해 열기 수정을 위해 닫힘

감사


JavaScript에서 많이 사용합니다. 다른 일이 발생할 때마다 어떤 종류의 조치를 취해야하는 다양한 위젯이 너무 많을 수 있습니다. 객체 소유권의 실제 계층이 없습니다. 모든 객체에 대한 참조를 모든 객체에 전달하거나 모든 객체를 전역으로 만드는 대신 특정 위젯 내부에서 중요한 일이 발생하면 해당 위젯을 모든 종류의 코드로 채우는 대신 "/ thisWidget / somethingHappened"를 게시 할 수 있습니다. 다른 위젯의 API에. Java Spring 프레임 워크에서 호출하려는 모든 "배선"또는 "플러밍"을 포함하는 단일 클래스가 있습니다. 이 클래스는 내 모든 위젯에 대한 참조를 포함하고 각 다양한 이벤트 발생 후 발생하는 작업에 대한 모든 코드를 포함합니다.

It is centralized, easy to access and maintain, and if one thing changes or I want a new process to occur on a specific event, I don't have to search through every single class/object/widget to try to find out where something is being handled. I can just go to my "operator" class -- the one that handles all the "wiring" when a particular event happens, and see every repercussion of that event. In this system, every individual widget is completely API agnostic of the other widgets. It simply publishes what has happened to it or what it is doing.


I'm having trouble understanding what you're really asking in your question. You give an example of a simple event bus which is actually just Observable with a different name, then you say;

For these reasons I think, that for most software, Observer pattern is better than event bus. What do you think about event bus, does it make any good sense for typical applications?

..but given your example, they are the same. This makes me wonder if you have ever used something like a Enterprise Service Bus. At a base level an ESB logically does the same thing as the observer pattern, but commercial products add much, much more. Its like an event bus on steroids. They are complicated software products and offer;

Message pickup
Generate events by listening to various endpoints. The endpoint can be a listener (such as a HTTP server), a messaging system (such as JMS), a database or pretty much anything else you want.

Message routing
Take your event and send it to one/many endpoint. Routing can be pretty smart, the bus might route the message depending on the message type, the message contents or any other criteria. Routing can be intelligent and dynamic.

Message Transformation
Transforms your message into another format, this can be as simnple as from XML to JSON or from a row on a database table to a HTTP request. Transformation can occur within the data itself, for example swapping date formats.

Data Enrichment
Adds or modifies data in your message by calling services along the way. For example if a message has a postcode in it the bus might use a postcode lookup service to add in address data.

..and lots, lots more. When you start looking into the details you can really start to see why people use these things.


Because it can be an important step in the way to decouple the application modules to a service based architecture.

So in your case if you have not the intention to decouple the modules of your application into isolated services then the native implementation of the Observer pattern will make it a simpler solution.

But If you want to build lets say a micro-services architecture the event-bus will allow to get the benefits of this architecture style so you could for instance update and deploy just some part of your application without affect others, because they are just connected through the event-bus.

So the main question here is the desired level of application components decoupling.

Some references about it:


A good analogy is that of a telephone exchange, where every handset can dial to every other handset. A compromised handset can tune into other conversations. Program control flows like wires(cyclomatic complexity anyone!) This is similar to the requirement of having a connection/physical medium between two end points. This is So for N handsets instead of having NC2 (Combinatorial logic) flows for every new handset we tend to get N flows.

A reduction in complexity implies easy to understand code. Lets start with the prominent points you have highlighted: 1. Global knowledge 2. Intrusive modifications.

Global Knowledge: Consider message event to be an envelop. From event handler/sender perspective there is no data being exposed, it is seeing an envelop (unless an derived class tries to do some inspection using 'instanceof' checks). In a good OOP design, this would never occur.

Intrusive modifications: Instead of having a event specific listener approach, one can use a global event handling approach. As such we have a global event type (on which data is piggy backed and down-casted). This is much like the PropertyBeanSupport model in Java. With a single event type we are required to have a single sender and listener types. This implies you need not modify the bus/listeners every time you see something new. The ugly down-casting can be soothened using Adapter pattern (Please don't start that another level of redirection quote!). Programmers can write assembly in any language. So need for commonsense and smartness can not be substituted. All I intend to state is it can be a effective tool.

The actual event receivers can use the listeners (composition/proxy) easily. In such a Java code base, listeners would look like stand alone inner class declarations (with unused warning being flagged in certain IDEs). This is akeen to two players on the beach playing a ball game, the players don't react until they see the ball.

'@duffymo' points out another interesting aspect: 'Single point of failure'. This would/can in theory effect any object residing in memory(RAM) and not specific to MessageHandlers.


As a practical example, our app sync's with a web service every x number of minutes, and if any new data is received, we need to update the GUI. Now, because the SyncAdapter runs on a background thread, you can't simply point to a textview and modify its properties, you have to bubble up an event. And the only way to make sure you catch that event is if you have a shared (static,singleton) object passing that event around for subscribers to handle.

참고URL : https://stackoverflow.com/questions/3987391/why-people-use-message-event-buses-in-their-code

반응형