Subscriber/Observer Pattern

Share your advanced PureBasic knowledge/code with the community.
Phollyer
Enthusiast
Enthusiast
Posts: 145
Joined: Sat Jun 03, 2017 3:36 am
Location: USA, Texas
Contact:

Subscriber/Observer Pattern

Post by Phollyer »

I'm sure this is child's play for most of you...I was board so I implemented the Subscriber pattern in Modules...

Code: Select all

DeclareModule  SUBSCRIBER
  Structure Subscriber
    ID.i
    Name.s
  EndStructure
  Declare Update(*ToWhom.SUBSCRIBER::Subscriber, News.s)
EndDeclareModule

Module SUBSCRIBER
  Procedure Update(*ToWhom.SUBSCRIBER::Subscriber, News.s)
    MessageRequester("NEWS Broadcast to "+ *ToWhom\Name, News, #PB_MessageRequester_Info)
  EndProcedure
EndModule



DeclareModule PUBLISHER
  
  Structure Publisher
    News.s
    List Subscribers.SUBSCRIBER::Subscriber()
  EndStructure
  
  Declare AddObserver(*Observer.SUBSCRIBER::Subscriber, *Publisher.PUBLISHER::Publisher)
  Declare RemoveObsererver(*Observer.SUBSCRIBER::Subscriber, *Publisher.PUBLISHER::Publisher)
  
  Declare NotifyObservers(*Publisher.PUBLISHER::Publisher)
  Declare SetNews(News.s, *Publisher.PUBLISHER::Publisher)
  Declare UpdateDailyNews(*Publisher.PUBLISHER::Publisher)
  
EndDeclareModule

Module PUBLISHER
  Procedure AddObserver(*Observer.SUBSCRIBER::Subscriber, *Publisher.PUBLISHER::Publisher)
    AddElement(*Publisher\Subscribers())
    *Publisher\Subscribers()\ID = *Observer\ID
    *Publisher\Subscribers()\Name = *Observer\Name
  EndProcedure
  
  Procedure RemoveObsererver(*Observer.SUBSCRIBER::Subscriber, *Publisher.PUBLISHER::Publisher)
    Protected X
    For X = ListSize(*Publisher\Subscribers())-1 To 0 Step -1
      SelectElement(*Publisher\Subscribers(), X)
      If *Publisher\Subscribers()\ID = *Observer\ID And
         *Publisher\Subscribers()\Name = *Observer\Name
        DeleteElement(*Publisher\Subscribers())
        Break
      EndIf
    Next
  EndProcedure
  
  Procedure NotifyObservers(*Publisher.PUBLISHER::Publisher)
    Protected X
    For X = ListSize(*Publisher\Subscribers())-1 To 0 Step -1
      SelectElement(*Publisher\Subscribers(), X)
      SUBSCRIBER::Update(*Publisher\Subscribers(), *Publisher\News)
    Next
  EndProcedure
  
  Procedure SetNews(News.s, *Publisher.PUBLISHER::Publisher)
    *Publisher\News = News
  EndProcedure
  
  Procedure UpdateDailyNews(*Publisher.PUBLISHER::Publisher)
    PUBLISHER::NotifyObservers(*Publisher)
  EndProcedure
  
EndModule



MSNBC.PUBLISHER::Publisher

George.SUBSCRIBER::Subscriber
George\ID = 1
George\Name ="George"

PUBLISHER::AddObserver(@George, @MSNBC)

Martha.SUBSCRIBER::Subscriber
Martha\ID = 1
Martha\Name ="Martha"

PUBLISHER::AddObserver(@Martha, @MSNBC)

PUBLISHER::SetNews("Breaking NEWS...Nothing Happened!", @MSNBC)
PUBLISHER::UpdateDailyNews(@MSNBC)


Little John
Addict
Addict
Posts: 4791
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Subscriber/Observer Pattern

Post by Little John »

Hi, some remarks.

Since this is in the “Tricks 'n' Tips” section of the forum, it wouldbe good if the code is as educational and straightforward as possible.
In the above procedure RemoveObsererver(), there is no need to use an index variable together with SelectElement(). And SelectElement() is rather slow. This is better:

Code: Select all

  Procedure RemoveObsererver(*Observer.SUBSCRIBER::Subscriber, *Publisher.PUBLISHER::Publisher)
     ForEach *Publisher\Subscribers()
        If *Publisher\Subscribers()\ID = *Observer\ID And
           *Publisher\Subscribers()\Name = *Observer\Name
           DeleteElement(*Publisher\Subscribers())
           Break
        EndIf
     Next
  EndProcedure
The same applies to procedure NotifyObservers().
 
 
George\ID = 1
[...]
Martha\ID = 1
An ID must be unique. Assignment (and reuse) of IDs should be handled automatically by procedures AddObserver() and RemoveObserver().

EnableExplicit is missing 3 times: In each module, and in the demo part of the program.
Last edited by Little John on Fri Sep 05, 2025 7:43 pm, edited 1 time in total.
User avatar
Kiffi
Addict
Addict
Posts: 1504
Joined: Tue Mar 02, 2004 1:20 pm
Location: Amphibios 9

Re: Subscriber/Observer Pattern

Post by Kiffi »

RemoveObsererver -> RemoveObserver :wink:
Hygge
Little John
Addict
Addict
Posts: 4791
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: Subscriber/Observer Pattern

Post by Little John »

:-)
User avatar
Skipper
User
User
Posts: 57
Joined: Thu Dec 19, 2024 1:26 pm
Location: NW-Europe

Re: Subscriber/Observer Pattern

Post by Skipper »

Hi Phollyer,

For code like this it would have been nice to have generics...

Thanks for posting!

Cheers,
Skipper
<< Win-11 (x64) / Mint linux (x64) / MacOS Monterey (x64) >>
User avatar
Piero
Addict
Addict
Posts: 950
Joined: Sat Apr 29, 2023 6:04 pm
Location: Italy

Re: Subscriber/Observer Pattern

Post by Piero »

Can you please stop?
I'm tired of learning from this Forum! :? :x
User avatar
idle
Always Here
Always Here
Posts: 5915
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Subscriber/Observer Pattern

Post by idle »

Thanks for sharing
you could also add a mutex to make it thread safe.
Post Reply