design-patternsumlmodelingobserver-patternclass-diagram

Modelling Gof Observer patterns in UML


I am in the process of modeling my project, which I will subsequently implement in Java, utilizing UML. The focus of my project is the management of a gym. Currently, I am working on modeling my GoF Observer diagram. From my understanding, it seems inappropriate to allow my Graphic Controller to directly communicate with the models (entities)—please correct me if I'm mistaken.

On the contrary, if I let my application controller implement the Observer pattern, how can I effectively notify the graphic controller when an exercise changes its status? The graphic controller is responsible for handling inputs and displaying outputs from the application GUI views, communicating with the application controller through bean classes.

The application controller, on the other hand, plays the role of 'doing the work.' It retrieves data from the graphic controller through beans and carries out the necessary activities, such as rejecting a request or removing an exercise. Additionally, it can fetch data from the database through other classes (DAO), which, like the beans' classes, are not discussed in this example.

Here, I present my two ideas: enter image description here

enter image description here

Subsequently, I had another idea, and here it is:

I introduced an ExerciseInventory class, which has two lists as attributes: exList, inherited from the ExerciseCatalogue class (which encompasses all the exercises in my database), and activeExerciseList, containing exercises with the status set as active (status can be active/suspended). In this scenario, the concrete observer monitors each exercise's status and updates the activeExerciseList in the event of any changes.

However, I encounter a single issue with this approach: unfortunately, the Observer Pattern traditionally assumes a multiplicity of 1..1 between the concrete observer and the concrete observable (in this case, the 'entity' Exercise). In my situation, the multiplicity is 1..N because the concrete observer observes many exercises, and I'm uncertain whether this is still a viable idea or not.

Here's the modeling:

enter image description here


Solution

  • Observer pattern in Java

    The original GoF observer makes observable and observer bot a base class. The first question in a Java design is whether they should remain base classes or rather interfaces to be implemented. Your choice of having the observable be a base class (probably to benefit from a default implementation for the attachment and detachment of observers) and the observer an interface is valid (but when you use the dashed interface realisation arrow, you should clarify «interface»).

    In the case of the observable and the observer, the multiplicities are in general 0..1 and * respectively, because each observable can have several observers, and each observer can observe at most one observable, but potentially no observable as long as it is not attached to an observable.

    However, GoF explicitly mentions page 297 that the design may allow a same observer to observe more than one observable. The multiplicity would then be * and * respectively. The usual trick to do this is that the observable calls the update() passing itself as an argument. So your having the same observer for several exercises is perfectly possible, without going for your third approach.

    An improvement to your design would be to have several observers: one observer for the exercises, and one for ExercisesForWorkoutRoutine, because I assume you'd have in your UI a view for the exercise details and a view for the list of exercises in the routine.

    Overall design

    The first two alternatives depend on the architectural model that you chose:

    Your last design seems fine at first sight, however by making the ExerciseInventory inherit an exercise catalogue is confusing. As already said the many-to-many variant of the observer doesn't require this, and a second observer for the workout routine seems a cleaner approach.

    UML remarks

    Let's clarify the multiplicities. For each association, there is not a single multiplicity in the middle of the line, e.g. 1..1 between concrete observer and concrete observable, but two multiplicities, one at each end of the association (see above in the explanations for the observer).

    As a side remark, you do not need to duplicate the association between the concrete observable and the concrete observer, as the associations are inherited as well. If you want to narrow down the associated entities, you should indicate {redefines} to avoid giving the impression that there are two distinct associations.

    Now last but not least, the shared aggregation (white diamond) is no longer defined as a part-whole relationship in UML. For the last 20 years, the UML specifications do not give anymore any special semantic to the shared aggregation. So, if your design does not need composite aggregation (composition), you should prefer a simple association with the correct multiplicities. (and if your teacher still teaches the part-whole thing, please refer him to page 112 of the UML 2.5.1 specification - or page 40 of the ISO/IEC 19505 version of UML, which mentions whole/part on indicated page 42 for composition only)