There are several incarnations of Observer pattern: Listeners, Events etc. (am I right?)
But today we found we have no agreement among team members - is it possible that Listener (Observer) affect execution of the method which invokes it.
The example was proposed as following: when the deal is saved via DealDao, it could fire an event which would be caught by some Listener which will:
update calculated fields in the deal (some fees etc.);
create some dependent entities.
I myself greatly dislike this approach - for example because if update of dependent entity in the listener throws an exception, the deal update should be rolled back too.
But it seems unnatural that Listener forces the subject to roll back.
In general if you are changing the behavior of the object then you may be implementing the Strategy Pattern not the Observer Pattern.
Modifying the model itself in response to observed events on it can lead to very complicated behavior so I wouldn't really recommend it but it is valid.
Generally try to think about the "flow" of data and operations through your system. If you can make the flow always go in one direction (or at least have as few loops as possible) then the whole thing becomes a lot more simple to manage and understand.
Adding an observer is "down flow" from the original data. If that observer then goes back and modifies the original data then that is flowing upstream and makes the behavior of your whole program a lot more complicated. For example what happens if that change then triggers another event, which then comes back into the same observer again, etc? Someone tracing through the execution is going to find unexpected data changes until they find that observer and you run into the potential for recursive loops that stack overflow and all sorts of similar fun and games.
If there are no listeners to DealDao, will the deal be saved at all?
If yes, then you actually have an implicit listener which actually does saving operation. Then, when another listener is added which updates fields in the deal, then we have two listeners which operate on the same object. This is clearly violation of encapsulation principle which may cause problems. But Observer Pattern is not in vain: similary, you could get same effect in other way. As user Tim B pointed, first design flow of data with minimum of loops, that is, as a graph with nodes and edges, and let each node be well-defined object (in OOP sense). Only after that, think how to implement it, and Observer Pattern is a valid option.
Related
Hello I am trying to implement an analog clock using the Observer design pattern. I have understood the theory of how it works but when I was coding I couldn't understand the difference between notifyObserver (Observable) and update (Observer), more specifically: when and where do we use notify versus when and where do we us update? They seem to have the same purpose of letting know the observes that something in the program has changed, but they do it differently, which is what I don't quite understand.
Also, I haven't understood very well where the addObserves method needs to be put in order for it to observe.
when and where do we use notify versus when and where do we us update
notifyObservers is an Observable method which has the responsibility to iterate through all the observers registered with it and call their individual update method.
update method belongs to the Subjects which contain the actual logic of what needs to be done for individual Subjects when the notification happens. This can be different for different subjects. You can read more here on this subject.
Fair warning: I have no idea what I'm doing, so even the asking of this question may go awry.
I'm wanting to update state on a simple object (the Aggregate) and then provide the UI with a projection of the changed object. Here's my aggregate object (command handler exists, but not shown here).
#Aggregate
public class Widget {
#AggregateIdentifier
private String id;
private String color;
...
#EventSourcingHandler
public void on(ChangeColorEvt evt) {
color = evt.getColor();
}
...
}
...and here is my projection:
public class WidgetProjection {
private final EntityManager entityManager;
private final QueryUpdateEmitter queryUpdateEmitter;
...
#EventHandler
public void on(ChangeColorEvt evt) {
ProjectedWidget projection = entityManager.find(ProjectedWidget.class, evt.getId());
projection.setColor(evt.getColor());
queryUpdateEmitter.emit(FetchWidget.class, query -> evt.getId().startsWith(query.getFilter().getIdStartsWith()), projection);
}
...
}
The QueryHandler does what you would expect, finding the instance and returning it.
So here are my questions:
Why do I need the EventSourcingHandler in the Aggregate? That is, it
appears to do work, but the result isn't stored or sent anywhere.
So, that becomes my next question: After executing the EventSourcing
Handler, is the resulting instance of Widget (not the projection)
stored, seen, or sent anywhere?
If EventSourcingHandler is indeed needed, is there any way to avoid
having two independent copies of my business logic (one in
EventSourcingHandler, and one EventHandler)? I really hate the idea
of having to update the same business logic in two places.
I appreciate any clarity the group can provide. Thanks for your help!
I hope I can help you out with this question!
The short answer would be:
The necessity of using the #EventSourcingHandler really depends on how you want to model your application.
Now, that doesn't say much, so let me elaborate a little why I am stating this.
In answering your questions I am assuming that your desire is to create an application where you follow the ideas of DDD, CQRS and Event Sourcing. Thus, the concepts which Axon tries to simplify for you whilst building your application.
Let me go over your numbered questions from here:
The reason you'd need #EventSourcingHandler annotated functions in your Aggregate, is to (1) update the Aggregate state based on the (2) events it has published. To go to point 1, why would you update the state of your Aggregate? As your Aggregate is the Command Model of your application, it is tasked with making the decisions based on the commands it receives. To be able to make decisions, sometimes an Aggregate needs state, but sometimes it does not. So in the Widget example you've shared, I'd assume that the color field is no used at all to drive business logic later on, hence you could perfectly omit this state from the Aggregate without any problems. With the second point of my response I try to point out that an Aggregate will only ever handle the events which originate from itself. This is as the events are the source of your Aggregate, as the events constitute all the delta's which have occurred on that given model.
Your following questions fits nicely with proceeding the explanation I've started in point 1. The answer is quite simple, your Widget Aggregate is not stored anywhere, not as is. Every time you'd retrieve your Aggregate from the Repository (this is done automatically for you in Axon), which defaults to an EventSourcingRepository in Axon, all the Events for that given Aggregate will be retrieved from the Event Store. Than, an empty Aggregate instance is created and the framework will replay all the events it has found for that exact Aggregate instance. You're thus effectively Event Sourcing your Aggregate every time a new command comes in. This might sound a little overkill, as the number of events for a given Aggregate might grow to quite a large set. This can be solved by doing things like making snapshots of the Aggregate.
If this form of splitting your application in a dedicated part which deals with your business logic, the Command Model, and the part which simply returns a Query Model as an answer, the Query Model, then you could decide to have a State Stored Aggregate. So note, your are not required, at all, to do Event Sourcing when using Axon; it's just the default modus operandi for the framework. Thus I understand the felt concern from your part, that you're duplicating your logic. You can however strictly separate the part which makes all the decisions to be held in your Aggregate.
The Query Model (in your example the ProjectedWidget) can be stored in what ever format and in what ever database/tool you'd like, ideally without any business logic.
If you do find yourself adding business logic in the Query side of your application, this might suggest you should upgrade this bit as an event originating from your Aggregate's.
I hope this brings you some insights into why you'd go for Event Sourcing to begin with. This article describes CQRS in a little more detail than I could do here, and this link for Event Sourcing; hope they might serve as a more thorough explanation than I just gave you.
I have a problem whereby I have a class Item, which has a list of Subitems. When a child item has been changed or deleted, I need the parent Item to know about it.
I was thinking that the Observer pattern would come in handy here. But does it make sense for an Item class to both extend extend Observerable and implement Observer?
Cheers.
Yes it makes sense sometimes to have an observer also be observed.
Ask yourself why you want to apply the pattern, however. Observing just to give updates might be more complicated to debug, compared to just updating directly, e.g., the child calls his parent when he updates.
Generally, Observables don't want to know the details about their Observers (decoupling, information hiding) so that you can make virtually any class an Observer. If that is what you need, then the pattern is good for you. If not, then adding this may result in needless complexity (harder to understand and debug the code).
Edit (I had this backwards): Do your child (Observable) items already know all the details about their parents (Observer)? If they do, then using Observer might be over-design. If children don't want to know the details of their parent, then Observer could be useful.
When making observers be observable, watch out for cycles https://stackoverflow.com/a/964820/1168342
Your argumentation and situation make sense to use Observer Design pattern. There is very handfull article about Oberver design pattern. There is also very simple example in java so there is no sense to paste it here. Please look on it.
The simplest answer is when you find that you have events flowing in both directions, most likely it is time to introduce a Mediator. Sometimes these objects are coordinators. Most people consider the Controller in MVC a Mediator.
The alternative is to create a peer protocol, which is maybe less structured, and more elastic in that you can do things like discovery that are generally not part of Mediator as it knows the parties it's coordinating in advance.
So my answer would be just making every thing observe various aspects of other things in its ecosystem will lead to chaos pretty quickly unless some kind of communication protocol is in place.
If you need to add a subitem to an item or remove one from it, you have to call a method on that item instance. The methods could look like:
public void addToSubitems(Subitem subitem);
public void removeFromSubitems(Subitem subitem);
So the item stays responsible for managing its subitems. When returning a collection of subitems from the item, always return an unmodifiable collection. By making the Item class responsible for managing the items, it has the possibility to take aktions on addition, removal, etc.
If the item also needs to get notified about changes of its subitems, you can also consider making the subitems immutable and implementing a change as an atomic replace of an items subitem. Or the item will attach an observer to a subitem as soon as it is added to that item.
I have changed my app to use MVC and it has gotten pretty slow.
Description:
The application has a number of 5 composites, each composite represents different data and is not always showing
The app is using MVC and I am passing the model to each composite when an update occurs.
I am rebuilding a Tree (and all tree items) every time a notify is recieved, however, only one of the tree items would have changed, so this is possibly a waste.
Due to the style of the app I have to even notify() for insignificant things like changing the text in a text box or selecting a menu because I have a saved icon that turn to unsaved whenever something is changed in the tree Item.
All the composites are implementing the same Observer Interface, so all are getting updated on every notify().
Can someone give me some tips on what I should do to speed this app up. Which of the above might be more CPU hungry than others, ie, is rebuilding a Tree with < 20 items on every notify() going to use that much CPU time, do I need to re-design this? Should I create a seperate interface such as SaveStateChanged that will only notify the tree, or is this just a waste of time.
When an application is getting slow, then most time is often not spent performing the JavaScript calculations themselves (e. g. I don't believe, that just calling a lot of observers is a problem - it depends on what they do!). Very often, slowness is caused by things like redundant layout (e. g. when each of the observers causes a layout call). Sometimes, lots of DOM manipulations can also be a problem (mainly with Internet Explorer).
I would suggest to play a little bit with Speed Tracer, especially the redundant layout example. If that's not the specific problem in your application, you should be able to take a similar approach as shown in the example to track it down. Use markTimeline("String") to make special parts of your code show up clearly in Speed Tracer's graphs.
The first step you need to take is to isolate exactly where the performance problem is occurring. You've identified some good possible candidates, but you'll want to back that up with cold hard stats.
You may find you only need to address one of the above points, or that there might be another sticking point entirely
I suggest you get rid of the Observer interface in favour of something more finegrained. Look at the MVC architecture in Swing where a JTree is associated with a TreeModel and implements TreeModelListener interface to hear of changes to the model. The TreeModelListener interface has specific methods called by the model to indicate nodes changing, being added or removed from the tree. In addition it has a TreeModelEvent which provides even more data about which nodes are affected. If the model tells you precisely what has changed you will have a lot more scope for reacting intelligently from your listener implementations.
I just started playing with Observable, Observer and it's update() method and I can't understand what should I do when different actions call notifyObservers().
I mean, my Observable class has a few different methods that call setChanged() and notifyObservers() in the end. Depending on the called method, some part of the UI (Swing) needs to be updated. However, there is only one update() method implemented in the Observer class.
I though of passing something to the notifyObservers() method and then I can check the argument on update() but it doesn't feel like a good way to do it. Even if it did, what should I pass? A string with a short description of the action/method? An int, like an action/method code? Something else?
What's the best way to handle this situation?
in general you should update everything from the observable when you get a call to update(). if that is not practical, you can pass a hint to notifyObservers().
the gang-of-book says that one of the consequences of the observer pattern is:
"Unexpected updates. Because observers have no knowledge of each other's presence, they can be blind to the ultimate cost of changing the subject. A seemingly innocuous operation on the subject may cause a cascade of updates to observers and their dependent objects. Moreover, dependency criteria that aren't well-defined or maintained usually lead to spurious updates, which can be hard to track down.
This problem is aggravated by the fact that the simple update protocol provides no details on what changed in the subject. Without additional protocol to help observers discover what changed, they may be forced to work hard to deduce the changes.
"
also under implementation, they say:
"Avoiding observer-specific update protocols: the push and pull models. Implementations of the Observer pattern often have the subject broadcast additional information about the change. The subject passes this information as an argument to Update. The amount of information may vary widely.
At one extreme, which we call the push model, the subject sends observers detailed information about the change, whether they want it or not. At the other extreme is the pull model; the subject sends nothing but the most minimal notification, and observers ask for details explicitly thereafter.
The pull model emphasizes the subject's ignorance of its observers, whereas the push model assumes subjects know something about their observers' needs. The push model might make observers less reusable, because Subject classes make assumptions about Observer classes that might not always be true. On the other hand, the pull model may be inefficient, because Observer classes must ascertain what changed without help from the Subject.
"
The second parameter to update() is of type Object, so you can pass anything appropriate. As you note, the approach is rather general. In contrast, a class that maintains an EventListenerList can get a degree of run-time type safety when used as specified.