Is there any technical reason for the Observer pattern or similarities not to be used independently of the observed object?

Asked

Viewed 151 times

10

We often use things we don’t even think about because it’s like this.

I don’t like to put mechanism bumpers on object that is of specific domain.

If I have a screen control or a client who has some action that triggers an event my normal is to use some form of event where the object has a list of subscribers that obviously grows as it gets interested objects (observers) in some state change or behavior that this observed object is willing to warn has occurred, is occurring or will occur. The control mechanism stays in this object and has the cost in it.

I wondered if it is not more interesting to have a separate object of observation, then this object that was observed informs the object of observation that it has available events and the observer objects sign these desired events. This whole object is responsible for the observation mechanism and the objects that communicate do not have their own mechanisms reducing their responsibility, apparently improving cohesion and coupling.

I worry mainly about the object carrying state that is not part of his domain. I know it’s precious in many cases and I shouldn’t worry too much about it. But the question remains whether from the strict point of view of engineering it makes sense to do something like this.

I don’t want to know which is the best, but whether I’m seeing the big picture properly or missed something important.

Only illustrative example well simplified and naively in pseudocode:

class Score
    value = 0
    Increase() {
        value++
        Changed(this)
    }
    Score() {
        RegisterEvent(this, Increase)
    }
    ~Score() {
        UnregisterEvent(this, Increase)
    }

class Observation {
    observables[] = new[]
    RegisterEvent(obj, method) {
        observables[obj << ptrLength + method] = new[]
    }
    UnregisterEvent(obj, method) {
        observables[obj << ptrLength + method] = null
    }
    SubscribeEvent(obj, method, action) {
        observables[obj << ptrLength + method] += action
    UnsubscribeEvent(obj, method, action) {
        observables[obj << ptrLength + method] -= action
    }
}
class App {
    static player1 = new Score()
    static player2 = new Score()
}
class Screen {
    Screen() {
        SubscribeEvent(player1, Score.Increase, PaintScore1) {
        SubscribeEvent(player2, Score.Increase, PaintScore2) {
    }
    ~Screen() {
        UnsubscribeEvent(player1, Score.Increase, PaintScore1) {
        UnsubscribeEvent(player2, Score.Increase, PaintScore2) {
    }
    PaintScore1(obj) { ... }
    PaintScore2(obj) { ... }
}
class Fire {
    ...
    Reached(player) {
        (player == 1 ? player1 : player2).Increase()
    }
}

Would this be the same thing as the Mediator standard? If it is, would the Mediator be a substitute for the Observer? Or they serve different purposes. With the advent of Mediator would the Observer be obsolete? Or would they complement each other? Or would it be wrong for them to complement each other?

Is this the Event Aggregator? And is this just one of the countless things I thought I invented? Dammit Fowler! P

  • 1

    I do not know if I understand very well, the proposal you described has a certain resemblance to the Mediator Pattern or the combination of Mediator + Observer. In case I didn’t understand it right, can you explain to me the difference between what you are proposing and what Mediator Pattern does not solve?

  • @Tommelo edited, see if help answer. I’ve seen the Mediator, but I still have no experience with it. In fact the idea came seeing an implementation of it, but I saw no events. There the doubt may be just what you want to know :)

  • Ah, now it’s clearer! Another thing you remember is the Event Aggregator.

  • @Tommelo if he thinks there’s an answer putting these things...

1 answer

1


Is there any technical reason why the Observer or Simiandos pattern should not be used independently of the observed object?

From the point of view of cohesion and coupling, both the Subject (Observed) how much the Observers (Observers) are independent, that is, the operation and the responsibility of a "Subject" does not depend on Observers and, no matter what the type and specialization of the objects involved, all only need to respect a "contract"(interface) for example.

Illustrative example:

Interface Observer

public interface Observer {

    void onStateChanged(String attribute, Object oldValue, Object newValue);    
}

Interface Subject

public interface Subject {

    void addObserver(Observer observer);

    void removeObserver(Observer observer); 
}

A class "Observable"

public class Bird implements Subject {

    private List<Observer> observers = new ArrayList<>();
    private boolean flying;

    public boolean isFlying() {
        return flying;
    }

    public void setFlying(boolean flying) {
        boolean oldValue = this.flying;
        this.flying = flying;
        notifyObservers("flying", oldValue, this.flying);
    }

    @Override
    public void addObserver(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);     
    }

    private void notifyObservers(String attribute, Object oldValue, Object newValue) {
        observers.forEach(o -> o.onStateChanged(attribute, oldValue, newValue));
    }       
}

A class "Observer"

public class BirdObserver implements Observer {

    @Override
    public void onStateChanged(String attribute, Object oldValue, Object newValue) {
        System.out.println(String.format("%s %s %s", attribute, oldValue, newValue));       
    }
}

Note that even with a 1xN ratio, the cost (Pub/Sub) is quite low, I do not see the pub/sub mechanism outside the scope of an object "Observable".

So I don’t believe there’s a technical reason why it doesn’t happen separately in the Observer Pattern.

Now, your proposal bears a certain resemblance to two other Patterns:

So why not apply them in all cases where a pub/sub mechanism is required?

As I said earlier, the cost of the Observer has no significant impact on cohesion and coupling, if you have a simple application that needs pub/sub, this Pattern solves without problems.

Now, imagine an application that has more than 100 Observables (with multiple event types) and more than 100 Observers. To make it a little more complex imagine that some of these objects need a notion of states with Nxn relation. It would be a little complex to manage just with the Observer. In this case could enter the role of a "centralizer" to manage the exchange of messages between all, and that’s where enters the Mediator or Event Aggregator.

Therefore,

This would be the same thing as the Mediator standard?

Very similar proposal.

If so, would Mediator be a replacement for the Observer? Or do they serve different purposes.

No, one does not replace the other. They have similarities in facilitating communication between objects.

With the advent of Mediator would the Observer be obsolete? Or would they complement each other? Or would it be wrong for them to complement each other?

Also no, the Mediator does not make Observer obsolete. They can be used independently or they can complement each other, depending on the scenario applied.

This would be the Aggregator Event?

It’s a bit similar too.

And this is just one of the countless things I thought I invented?

Apparently yes, Sorry. = P

  • Only today I could read, very good! It is that similar is not the same thing. Still need to put into practice to see if it is something different, has pattern that looks identical, but there is a detail that makes it different. I don’t know if this story of "no significant impact on cohesion", use double for monetary value also has no, but error is error. I’m convincing myself that you’ve adopted a wrong strategy before, and I’ve seen a lot of complaining about the Observer, I think I’ve even answered something about it. I’m pragmatic, I think it’s okay to do certain things that aren’t ideal,

Browser other questions tagged

You are not signed in. Login or sign up in order to post.