473,397 Members | 1,961 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,397 software developers and data experts.

c#: inter-object event messaging (mediator pattern?)

Hi all,

Please bear with me as I've only started programming in C# 2 weeks ago
and this is my first contact with OOP.

I ran into a situation where I needed to catch an event in an object
that had no connection or reference to the object that triggered it.

It goes something like this: (not syntactically correct..it's just for
the idea)

main()
{ A a;
C c;
a.Run();
}

class A
{ B b;
C c;

Run()
{ // Trigger the Event here}
} // class

class B
{ C c;
}

class C
{ // Catch and handle the event here
}

Which means that the event would be handled by the 3 instances of C.

>From My research I gathered that I should be using something called
the "Mediator Pattern".
Unfortunately I could not find a working example of this.

Also, from what I was able to understand, to make it work with this
pattern would require that I derive class C from an abstract
"participant". Is that right ?

I then kind of gave up on trying to make it work with this pattern
(out of frustration at my failures) and proceeded to try and implement
something that I was a bit more familiar with (from my backgroung with
PCS):
The Publish / Subscribe model (is that also known as a pattern?)
I was pleasantly surprised that it worked.
Here's my working implementation:

All classes use the following:
using System;
using System.Collections.Generic;
using System.Text;

With the class Dispatcher also using:
using System.Collections;
class Program
{
static void Main(string[] args)
{
A a = new A();
C c = new C("C1");

for(int i = 1; i <= 3; i++)
{
a.Run(i);
}
Console.ReadKey();
}
}

class A
{
B b = new B();
C c = new C("C2");

public void Run(int i)
{
Dispatcher.Publish("MyEvent", "Hello #" + i.ToString());
}
}

class B
{
C c = new C("C3");
}

class C
{
private string name;

public C(string name)
{
this.name = name;
Dispatcher.Subscribe("MyEvent", OnMyEvent);
}

public void OnMyEvent(object appEventParams)
{
string textReceived = (string)appEventParams;
Console.WriteLine(textReceived + " received in " + name);
}

}

public delegate void AppEventHandler(object appEventParams);

static class Dispatcher
{
private static Hashtable registry = new Hashtable();

public static void Subscribe(string appEvent, AppEventHandler
appEventHandler)
{
Subscription(appEvent, appEventHandler, true);
}

public static void Unsubscribe(string appEvent,
AppEventHandler appEventHandler)
{
Subscription(appEvent, appEventHandler, false);
}

private static void Subscription(string appEvent,
AppEventHandler appEventHandler, bool add)
{
ArrayList list;

if (add)
{
if (registry[appEvent] == null)
registry.Add(appEvent, new ArrayList());

list = (ArrayList)registry[appEvent];
list.Add(appEventHandler);
}
else
{
if (registry[appEvent] != null)
{
list = (ArrayList)registry[appEvent];
list.Remove(appEventHandler);
}
}
}

public static void Publish(string appEvent, object
appEventParams)
{
ArrayList list;
AppEventHandler appEventHandler;

if (registry[appEvent] != null)
{
list = (ArrayList)registry[appEvent];

for (int i = 0; i < list.Count; i++)
{
appEventHandler = (AppEventHandler)list[i];
if (appEventHandler != null)
appEventHandler(appEventParams);
}
}
}
}
The ouput is:
Hello #1 received in C3
Hello #1 received in C2
Hello #1 received in C1
Hello #2 received in C3
Hello #2 received in C2
Hello #2 received in C1
Hello #3 received in C3
Hello #3 received in C2
Hello #3 received in C1

Here are my questions (about time you'll say...sorry about that too
long preambule):

1) Is 'this" somehow a valid implementation of the Mediator pattern
and if not, it is known under another name ? (I hope it's not one of
those anti-pattern)

2) If it's not a valid implementation of the Mediator pattern (or
another "good" pattern), is there any reason why you would advise
"against" this approach. Did I miss an obvious flaw ? Did I do a big
no-no ?

3) Could you "please" (pretty, pretty please) give me a valid
implementation of the Mediator pattern that would give me the exact
same behavior as in my example. (If possible please give me working
code)

4) Any other comments, good of bad, that you think might help me with
this problem.

Thanks a lot in advance.

Apr 25 '07 #1
1 4134
<ha*****@yahoo.comwrote in message
news:11*********************@b40g2000prd.googlegro ups.com...
>
[...]
Which means that the event would be handled by the 3 instances of C.

>>From My research I gathered that I should be using something called
the "Mediator Pattern".
Unfortunately I could not find a working example of this.
I'd never heard the phrase "mediator pattern" until your post. :) As near
as I can tell from the Wikipedia article on the topic, the "mediator
pattern" is simply a way of describing an inter-object communications
paradigm in which an intermediate (or "mediating") object handles the
communications.

It seems to me that if you have a general-purpose event to which a variety
of different classes may want to subscribe, then the mediator pattern makes
sense. If, on the other hand, you have a special-purpose event to which
only a specific class will subscribe, I don't think you need a mediator
class and the mediator pattern doesn't make sense.
Also, from what I was able to understand, to make it work with this
pattern would require that I derive class C from an abstract
"participant". Is that right ?
I guess that depends on how rigidly the authors of the "Design Patterns"
book have defined "mediator pattern".
I then kind of gave up on trying to make it work with this pattern
(out of frustration at my failures) and proceeded to try and implement
something that I was a bit more familiar with (from my backgroung with
PCS):
The Publish / Subscribe model (is that also known as a pattern?)
It seems to me that the publish/subscribe model you implemented is in fact
an example of a mediator pattern. Again, I suppose it really depends on how
rigidly the term has actually been defined. But in the code you wrote, an
intermediate class handles communications between other classes. As such,
that intermediate class could be thought of as a mediator, and the design
could be thought of as a "mediator pattern".
[...]
1) Is 'this" somehow a valid implementation of the Mediator pattern
and if not, it is known under another name ? (I hope it's not one of
those anti-pattern)
See above. I would call it an example of "the mediator pattern".
2) If it's not a valid implementation of the Mediator pattern (or
another "good" pattern), is there any reason why you would advise
"against" this approach. Did I miss an obvious flaw ? Did I do a big
no-no ?
I don't see anything obvious wrong with your implementation. It seems to me
that it could be a little more concise, especially if you don't really have
the need for named events (that is, if you really only have a single event
to deal with), since C# includes built-in support for a data type called an
"event" that wraps up the subscribe/unsubscribe functionality for you.
Likewise, if you know it will always be an instance of class C that
subscribes to the event, you could even have an explicit event within class
C to which instances add themselves and which is signaled by a specific
method in class C.

But all those are just variations on the theme, and if you really need the
general-purpose behavior you've implemented, then I don't really see much in
the way of significant improvements (I don't like the design of combining
both the subscribe and unsubscribe behavior into a single method, but that's
your choice I guess).

One minor quibble (besides the "two behaviors in one method I mention
above):

You might consider removing your ArrayList instance from the Hashtable
if you've just removed the last entry of the ArrayList. Not a big deal if
you have very few events, or if you have a lot of events but don't expect
any of them to be empty for very long (as in, clients only unsubscribe when
the application is shutting down). But it just seems nicer to me.

Now that you ask the question, it seems to me that the C# "event" is missing
something. That is, as near as I can tell you can only ever define a
specific instance of an event. You can't have the type of an event, which
means that you can't add a dynamically created event to a collection, which
means that you can't enjoy the type-safeness of events while at the same
time providing a named-event paradigm such as the one your Dispatcher class
does.

Maybe I'm wrong about the limitations of the C# "event". I'm no expert in
using them, and I might have missed something. If so, hopefully someone
else will pipe up. I think it would be really cool if you could use a
Dictionary to maintain a list of dynamically created events, indexed by
name. It wouldn't change the code you've suggested very much, but it would
allow it to be type-safe (that is, you would only be able to add delegates
of the correct type to a specific event).

Pete

Apr 25 '07 #2

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: gmtonyhoyt | last post by:
Okay here's the situation. What I'm looking for, is a sort of generic wrapper or API that will allow me to build threads with some kind of messaging system attached with it. The idea is that...
5
by: Joseph Geretz | last post by:
I need to communicate between two applications. The legacy application is in VB6. New development is in C#. Here's the scenario: The VB6 app will be pumping document files into a folder. We'll be...
1
by: Raf256 | last post by:
I have base template class A<B>, and son class B. Inside A<B> constrcutor, can I access a pointer to B, from "this"? like A<B>::A() : pointerToB(static_cast<B*>this) { } I will use the...
1
by: halekio | last post by:
Hi all, Please bear with me as I've only started programming in C# 2 weeks ago and this is my first contact with OOP. I ran into a situation where I needed to catch an event in an object that...
11
by: John A Grandy | last post by:
I'm in a vigorous debate at my work regarding objects assuming knowledge of the type their containing object. This debate pertains specifically to ASP.NET, but I have decided to post in the C#...
4
by: Mark | last post by:
Hi, I'm relatively new to Java, but have been a programmer for decades. I would like multiple instances of my Java app (on different computers on the same local LAN) to communicate with each...
3
by: Michael Justin | last post by:
Mufasa wrote: Message Oriented Middleware might be an option too: http://en.wikipedia.org/wiki/Message-oriented_middleware There are many very good (including Open Source implementations)...
6
by: kirk | last post by:
I have three events, using event handler methods as depicted below. Two of those event handler methods need to reset specific data whenever the other event left fires. I wasn't sure how to...
3
by: King | last post by:
This is a new test for object persistency. I am trying to store the relationship between instances externally. It's not working as expected. May be I am doing it in wrong way. Any suggestions? ...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.