Jump to content

Observer Pattern


Recommended Posts

Et al,

I had an opportunity that required me to learn VS Silverlight, which in turn meant I had to learn C#. While I was learning good programming style I came across the Observable pattern and framework classes. Very interesting. For those that don't know it here is the wiki. Here is what I think is the most common use case:

(1) You have a business model object. The business object is called Observable. The business object consolidates all data that makes up your application into a convenient location.

(2) Other pieces of you application (typically other objects) will register/unregister with the business object to request updates when the business object gets updated. The objects that register are called Observers.

(3) When the business object changes the Observers are notified and handed relevant information from the business object.

(4) The observer takes the relevant info and manipulates it the way it wants.

The most common use is for UI. Your business object changes and the UI object which has registered to it takes the new data and displays it in an original way outside the knowledge of the business object. The bonus is a very loosely coupled UI and Data.

Just wondering if anyone has attempted?

Link to comment

Sounds alot like NI's own PSP (Publish Subscribe Protocol). The only problem is that NI does not fully give us the ability to create

subscriptions that can be used to create user events. We can of course use the DSC toolkit, but IMHO it should be built into the NSV API

and available also in RT since it affords such a powerful architecture.

Link to comment
Just wondering if anyone has attempted?

The simplest form of the Observer Pattern in LabVIEW is "One VI generates a user event and gives it to any other VI that asks for it. That other VI then registers the user event refnum with an event structure and listens for the event."

There are many variations on that theme, some more successful than others, so let me point you toward one that I would use initially. The Observer Pattern needs two parts -- the independent model and the listening system. The independent model is what I was constructing withthe Actor Framework, presented at NI Week 2010. In the docx file that is part of the download .zip file, there is a description of how to set up listener relationships between the actors by selectively sharing the queue refnum. That isn't quite the same as the Observer Pattern. For the observer pattern, you would want to share around user event refnums -- create some sort of RegisterMe message class and send it to the model object and have it send back the user event refnum and then have the observer register that refnum on an event structure. You'd have to work out the details yourself, but I hope that's enough to get you started.

Link to comment

Under the heading of "THose who refuse to study history are forced to repeat it..."

I have a design pattern that I developed prior to LVOOP that was inspired by a design Pattern posted by Jim Kring that uses notifiers. My version has been called internally "Self Addressed Stamped Envelope" patern and sounds similar to what I read above.

The challenge that drove the pattern was I need a "viewer" that could display any of the signals acquired in an application but number of viewers and the channels were not known at development time.

How it worked.

All of the producers each had a loop running that acted ast the "marketing" department. The loop published a queue (implemented in an AE but a Singleton would do the same) ref along with a list of the channels it offered. This loop and queue would act as the "in box" for the marketing department who would watch for new requests coming (an entry in the queu with the name of the channel to monitor and a queue to use for the updates) in and when one was found pass that to the "Production" department who would include the requestors queue in the list of all queues it updated when new data comes in.

The main reason I chime in on this pattern is that is had kick-ass performance becuase all of the data was shared via queues and only minimal buffer duplications requied.

Done distracting for now,

Ben

Link to comment

Just wondering if anyone has attempted?

I think there are a couple of network Publisher/Subscriber examples kicking around the CR. I'm not sure if they qualify for an "Observer" pattern since some people seem to use both terms interchangeably whilst others use it specifically for events. I think also the "Top-Level Baseline" might qualify too.

Edited by ShaunR
Link to comment
Sounds alot like NI's own PSP (Publish Subscribe Protocol). The only problem is that NI does not fully give us the ability to create subscriptions that can be used to create user events. We can of course use the DSC toolkit, but IMHO it should be built into the NSV API and available also in RT since it affords such a powerful architecture.
Exactly. (We use DSC but shared variables and therefore shared variable events should be part of the LabVIEW core.) Overal NI-PSP provides what you need from the Observer Pattern, has good performance, works over a network(!), and (with DSC) adds logging. For many users I think it will be sufficient (and cheaper) to use the off-the-shelf solution. (If someone wants to make a better off-the-shelf solution that's fine, too!)
Link to comment

Just wondering if anyone has attempted?

Yeah, I've done it a couple times so I could easily bolt different user interfaces onto my app. (I'm terrible at making UIs look nice so I prefer to let others do that part.) UIs are the most apparent place they can be used, but there are other places where they can be useful. Acquired data usually goes to more than one place... a data logger and the UI. In some situations it might make sense to wrap your data collection component and expose it as an Observable object. (The observed object is usually called the "Subject")

It does add a lot of abstraction so it can be very daunting to those not familiar with the concept. After implementing it a few times now I only use it when I am reasonably certain there will be 2 or more observers. If there's only one observer I use a SlaveLoop object instead. It's far easier to understand and the SlaveLoop can easily be wrapped up in an observable class later on if additional observers need to be added.

Publish-Subscribe vs Subject-Observer

Here's my (quite probably incorrect) understanding of the differences between these two concepts:

In a publish-subscribe system, the publisher doesn't know how many, or even *if* any, other components are receiving the updates. It just sends out messages for whoever happens to be listening. Subscribers attach and detatch at will without the publisher knowing or caring that these things are happening. It's a true 1-to-n broadcasting mechanism.

In a subject-observer system the observers "registers" with the subject, who maintains an internal list of all observers. When the observer doesn't want to receive status updates anymore, it notifies the subject it wants to unregister and the subject removes it from the internal list. I think of it as n 1-to-1 links.

(These definitions seem backwards to me. When I subscribe to a magazine I have to notify the publisher if I expect to ever receive anything. And when I'm watching if I were ever to watch a cute girl crossing the street from the safety of my 3rd floor office, I certainly wouldn't run down there and tell her I'm observing her. But hey, who am I to go against convention?)

As near as I can tell they both meet the same high-level goal. One object, the publisher/subject, updates many other objects, the subscribers/observers, when something interesting happens. The differences seem to come out in how they are implementated, and to some extent, what kinds of things you can do with them. Still, I see a lot of gray area between them. I'll compare them using an example of a watchdog timer component that fires every 100 ms.

Publish-subscribe (PS) systems are--in principle--easier to develop. A very simple implementation is to create a loop that sends a user event when the timer expires. The publisher defines the user event data type and has a public "Get WatchdogTimerUserEvent" method that returns the user event refnum. To start receiving status updates, subscribers simply use that method to get the user event refnum and register their event structure for it.

Contrast that with a simple subject-observer (SO) implementation that preserves a 1-to-1 link with each of n observers. Each observer is going to have a unique user event refnum (or queue, functionally it doesn't really matter) meaning the subject has to maintain a collection of all the UE refnums internally so all observers can be notified. Managing the collection and creating new user events every time "Get WatchdogTimerUserEvent" is called is going to take more code and add some amount of complexity to the app.

So if PS is easier to implement, easier to understand, and does the same thing as a SO system, why would anyone bother with SO? There are a few reasons why I prefer it over PS, even though it takes more effort to implement:

1. Done correctly, SO is more robust than PS. PS exposes a single user event refnum to all subscribers. If one of those subscribers happens to incorrectly destroy the refnum *all* subscribers lose their connections. In SO, each observer only has access to its refnum so it can't disrupt communication between the subject and other observers.

2. Subject can self-terminate when they are no longer needed. Usually the components I consider for SO will have observers for the duration of the app. That makes it very easy to write self-terminating code that triggers when there are no observers remaining. (It's quite handy and one less thing for me to worry about during shutdown.) Producers will continue to exist until something explicitly instructs it to terminate.

3. SO systems can use queues for passing messages. PS systems must use user events. Writing apps where some components use users events to send messages and some components use queues to send messages is kind of ugly. In the general case clients need to create separate loops to service each of the queues (to make sure one of them isn't ignored by excessive messages to the other) and then forward the messages to a single common loop. There's nothing inherently *wrong* with writing an adapter loop to translate user events into queue messages; I just find it more convenient to use a single messaging technology.

Anyone else have other insights into the differences? Like I said, I don't know if my explanation is correct... it's just an explanation that makes sense to me (except for the backwards definitions) and helps me differentiate between them.

  • Like 1
Link to comment

In a publish-subscribe system, the publisher doesn't know how many, or even *if* any, other components are receiving the updates. It just sends out messages for whoever happens to be listening. Subscribers attach and detatch at will without the publisher knowing or caring that these things are happening. It's a true 1-to-n broadcasting mechanism.

In a subject-observer system the observers "registers" with the subject, who maintains an internal list of all observers. When the observer doesn't want to receive status updates anymore, it notifies the subject it wants to unregister and the subject removes it from the internal list. I think of it as n 1-to-1 links.

I think your pub/sub definition is really a broadcast definition (like UDP Multicast). I think the observer pattern is just a particular flavour of pub/sub as is "content-based" and "topic based". But I've only ever heard the term in context to events. In other areas I think it's called "List-based" pub/sub.

Edited by ShaunR
Link to comment

I think your pub/sub definition is really a broadcast definition (like UDP Multicast).

I'm really weak on networking technologies and terminologies, but I agree PS is equivalent to broadcasting. "Publish-subscribe" appears to be the terminology favored by the software community. The stuff I've read uses "broadcast" to describe what the component does, not label the abstract interaction pattern.

In general though, there's so much variability in what people mean when describing a component as "publish-subscribe" or "observer pattern" that it's hard to infer anything about the implementation other than, "the component sends out updates when something interesting happens."

I think the observer pattern is just a particular flavour of pub/sub as is "content-based" and "topic based".

I think you're right that SO is a subset of PS. In Labview it's pretty straightforward to migrate from a general PS model to a SO model. If the component has been decoupled correctly the change can be made in the publisher/subject without touching the subscriber/observer code or any of the client code.

Accroding to the producer-consumer wiki, "content-based" and "topic-based" refers to message filtering, or how the producer/subject exposes subsets of updates. It's a decision that can be made independently of the PS/SO decision. So while SO could be a particular flavor of generalized PS interactions, I view content/topic based filtering as chosing the topping to go on the ice cream.

------------------------------

I wrote the previous post last night at home. When I got to work this morning I checked to see what GoF has to say about it:

"A subject may have any number of dependent observers. All observers are notified whenever the subject undergoes a change in state. In response, each observer will query the subject ot synchronize its state with the subject's state.

"This kindof interaction is also known as publish-subscribe. The subject is the publisher of notifications. It sends out these notifications without having to know who its observers are. Any number of observers can subscribe to receive notifications." (p 294)

I thought it was interesting GoF has the observer invoking the Subject.Update method to get the new state information. My implementations have never required that much work from the observer. Instead I just pass the relevant data along with the notification. I can see how requiring observers to call Subject.Update is a more flexible general purpose solution for Labview. By giving observers more control over when they receive updated data you can reduce the number of data copies the subject creates. I haven't run into situations where I have enough observers or large enough data sets to have to worry about that, but it's nice to know what to do in case I ever do encounter that situation.

Link to comment

Publish-Subscribe and Observer Pattern are two names for the same thing. (Larman on p.468 explains a bit of the history of the terms and lots of web pages that explain they are equivalent.) (OK, very strictly speaking, the Gang of Four Observer Pattern is an Object-Oriented implementation, and I don't know exactly how NI implemented NI-PSP. On the other hand, NI-PSP has an interface--the shared variable--to the Shared Variable Engine, which manages the connections, so it serves the purpose.)

Head First Design Patterns walks you through an implementation of the Observer Pattern step by step. The authors recommend you know how to roll your own, even though there is a native implementation in Java (much like there are shared variables in LabVIEW) and you can just implement the provided interface.

If you are an application developer, I don't think you need to invest in doing your own implementation (unless you are way ahead of schedule...). If you want to make a new toolset to replace or at least compete with NI-PSP, super! (If so, you might take a look at the DDS standard.) In any event, learning how the Observer Pattern works is a great exercise!

Link to comment

3. SO systems can use queues for passing messages. PS systems must use user events. Writing apps where some components use users events to send messages and some components use queues to send messages is kind of ugly.

I usually use Notifiers rather than User Events. Many of my notifier subscribers don't run GUI loops at all. Otherwise, I don't think there's too much difference, but the APIs are very similar between Queues and Notifiers and it might clean up your code.

Link to comment

I'm really weak on networking technologies and terminologies, but I agree PS is equivalent to broadcasting. "Publish-subscribe" appears to be the terminology favored by the software community. The stuff I've read uses "broadcast" to describe what the component does, not label the abstract interaction pattern.

In general though, there's so much variability in what people mean when describing a component as "publish-subscribe" or "observer pattern" that it's hard to infer anything about the implementation other than, "the component sends out updates when something interesting happens."

I think you're right that SO is a subset of PS. In Labview it's pretty straightforward to migrate from a general PS model to a SO model. If the component has been decoupled correctly the change can be made in the publisher/subject without touching the subscriber/observer code or any of the client code.

Accroding to the producer-consumer wiki, "content-based" and "topic-based" refers to message filtering, or how the producer/subject exposes subsets of updates. It's a decision that can be made independently of the PS/SO decision. So while SO could be a particular flavor of generalized PS interactions, I view content/topic based filtering as chosing the topping to go on the ice cream.

------------------------------

I wrote the previous post last night at home. When I got to work this morning I checked to see what GoF has to say about it:

"A subject may have any number of dependent observers. All observers are notified whenever the subject undergoes a change in state. In response, each observer will query the subject ot synchronize its state with the subject's state.

"This kindof interaction is also known as publish-subscribe. The subject is the publisher of notifications. It sends out these notifications without having to know who its observers are. Any number of observers can subscribe to receive notifications." (p 294)

I thought it was interesting GoF has the observer invoking the Subject.Update method to get the new state information. My implementations have never required that much work from the observer. Instead I just pass the relevant data along with the notification. I can see how requiring observers to call Subject.Update is a more flexible general purpose solution for Labview. By giving observers more control over when they receive updated data you can reduce the number of data copies the subject creates. I haven't run into situations where I have enough observers or large enough data sets to have to worry about that, but it's nice to know what to do in case I ever do encounter that situation.

Microsoft have quite a nice definition of the pub/subs (including observer). the main differences seems to be how the clients obtain their updates and methods of registration. I'm more familiar with the content and topic (list) based since that's basically what "Dispatcher" and RSS are. But I've only used them in context with networking so events weren't applicable. I could see a use for observer invocation in something like LV web-services where you basically want to poll updates of remote devices. But it can be a bit prone to server over-loading if there are many observers.

Edited by ShaunR
Link to comment
  • 1 month later...

The main reason I chime in on this pattern is that is had kick-ass performance becuase all of the data was shared via queues and only minimal buffer duplications requied.

Done distracting for now,

Ben

I Appreciate the disctraction Ben

Good tip.

Link to comment
  • 2 weeks later...

Et al,

I had an opportunity that required me to learn VS Silverlight, which in turn meant I had to learn C#. While I was learning good programming style I came across the Observable pattern and framework classes. Very interesting. For those that don't know it here is the wiki. Here is what I think is the most common use case:

(1) You have a business model object. The business object is called Observable. The business object consolidates all data that makes up your application into a convenient location.

(2) Other pieces of you application (typically other objects) will register/unregister with the business object to request updates when the business object gets updated. The objects that register are called Observers.

(3) When the business object changes the Observers are notified and handed relevant information from the business object.

(4) The observer takes the relevant info and manipulates it the way it wants.

The most common use is for UI. Your business object changes and the UI object which has registered to it takes the new data and displays it in an original way outside the knowledge of the business object. The bonus is a very loosely coupled UI and Data.

Just wondering if anyone has attempted?

see this

and this

for downloading the framework see my response here

http://lavag.org/top...h__1#entry81818

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.