Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

This question relates to a question I asked earlier, which can be used for reference here: Is this the best way to approach this design? Is this an example of MVC?

While coding, I came across a realization that I am not creating 'loose coupling'. The way I am trying to solve the problem right now is creating an instance of the Log Collector Class in MAIN and passing it around to each form classes constructor.

Now, in theory, the Log Collector Class needs to be instantiated only once for the whole program run-time. I was thinking about using a Singleton Pattern for this class, but than thought that if two forms need to update this class at the same time, there would be an issue.

What would be the best way to have the Log Collector Class be shared via multiple forms without instantiating a new version of the Log Collector Class each time?

I've done some research before posting this question and have read some people say using a static class for this type of design. However, this doesn't seem like loose coupling to me.

Another Question

Would an Interface for the Log Collector Class be best used here for all forms wanting to communicate with it? For example:

public interface LogCollectorInterface
{
    void SendLogMessage(string logMessage);
}

Now when all forms want to communicate with the Log Collector Class, this is the only function they really need to use, SendLogMessage. Would instantiating the interface rather than the Log Collector Class be the best way to go about it?

FWIW, I am not sure if 'loose coupling' is the best direction is the way to go. It's one of those things I have caught on to while reading questions answered related to OOP. Being a new OOP programmer, it makes the most sense to me for both as an organizational standpoint and testing standpont.

Edit: This will not be a multi-threading application so no two forms can update the log collector class at the same time.

share|improve this question

2 Answers 2

up vote 3 down vote accepted

While coding, I came across a realization that I am not creating 'loose coupling'. The way I am trying to solve the problem right now is creating an instance of the Log Collector Class in MAIN and passing it around to each form classes constructor.

This is the best way to go.

A singleton will work, but carries with it all sorts of risks as your application grows, especially if you intend to implement unit tests.

The biggest problem with a singleton is it will be available to every single class in your application, not just the ones you've allowed access to it. And, as you'll see below, you can no longer segregate access to certain functionality by interface.

but than thought that if two forms need to update this class at the same time, there would be an issue.

This applies whether it's a Singleton or a single instance held by each form. But, if it's the form sending the message then, even in a multi-threaded application, this will all take place in the UI thread, so it isn't an issue.

If there's any danger whatsoever then a simple lock() will solve the problem for you.

Would an Interface for the Log Collector Class be best used here for all forms wanting to communicate with it?

Yes. Definitely. Even if you extend your mediator later to receive multiple messages from each form, have multiple interfaces and hold the same object in each field.

eg. (notice how a singleton isn't so attractive now?)

public class FooForm : Form
{
    private ILogCollector _logCollector;
    private IDataRequestor _dataRequestor;

    public FooForm (FormMediator mediator)
    {
        _logCollector = mediator;
        _dataRequestor = mediator;
    }

    // Stuff here
}

This way, if another form can only log exceptions and not request data, you needn't expose that functionality to the form.

This is the "I" in SOLID: Interface Segregation Principle.

share|improve this answer
    
+1, especially for the very completeness of this answer. –  Doc Brown May 24 '12 at 20:45
    
Thanks. Very informative write up. I did end up implementing it using this method and it worked perfectly. –  brazc0re May 24 '12 at 22:12

if two forms need to update this class at the same time, there would be an issue

Two forms can't update the same log collector object at exactly the same time unless they're in different threads. If you've got forms running in different threads but all sharing the same log collector object (or any other object), you need to think carefully about how to keep the log collector in a consistent state. That could get pretty complicated.

One common solution to this type of problem involve using a mutex to prevent two threads from both making changes at once. Another is to have the threads post messages to a queue that the log collector can then process in sequence. Before you jump into trying to solve the problem, though, read up on multithreaded programming. It's easy to go wrong here, and notoriously difficult to debug thread interaction problems.

share|improve this answer
    
Thank you for the reply. Now that I think about it more, two forms will not be able to update it as a design guideline. No multithreading is not something I plan on achieving. The reason for this is because my program will interact with updating hardware through RS-232, so there is no possible way two forms can communicate with the hardware at the same time. I'll read up on mutex also. –  brazc0re May 24 '12 at 18:20
    
If you are in Java you can mark the appropriate methods (or the whole class if necessary) synchronized to avoid programming your own locking implementation. That's only one way though; there are many ways to achieve exclusivity depending on your requirements. –  Michael K May 24 '12 at 18:42

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.