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.

I have many classes in my application responsible for behaviour- views, controllers, models, network- often the state of one class or system depends on another and I'm finding that classes that are primarily responsible for the behaviour for one system inevitably become dependees or dependers of other systems or classes. I've tried passing in interfaces of dependencies from the constructor of the system all the way to the class the depends on it and registering for events on it but this gets extremely complex and crazy and definitely violates OCP and SRP at least.

I'm considering making an event system that all event dispatching and listening classes would be coupled to, providing a layer of indirection for classes that require interaction with classes from other systems however in the worst case behavioural classes could be responsible for the behaviour of a class, handling events, and dispatching events- so that definitely also violates the SRP even though I'm pretty sure it would follow the OCP.

Is there a better solution out there? Am I applying these principles correctly? I'm very hesitant to use an event system as it will require most classes to be extremely tightly coupled with it.

share|improve this question

migrated from stackoverflow.com Jul 18 '12 at 14:15

This question came from our site for professional and enthusiast programmers.

    
I'm not sure this fits well to a single-question/definite-answer type format, but I'm very interested to see the discussion as well. –  hometoast Jul 18 '12 at 13:55
    
If by "behavior classes" you mean "verb" named classes then you are certainly doing OO wrong. Your alternative suggestion is also wrong. It sounds like you need a higher level class that can perform the connections between classes for you while keeping the listening/reporting classes unaware of eachother. Events work great for doing things like that. C# makes this very easy, the listening/reporting classes need never know about the other. The event just sends the necessary data, not instances of classes themselves. –  Dunk Jul 18 '12 at 14:56
    
By behavior classes I mean state machines that intercept calls or events on a class and act based on the current state- so for example if I have a class responsible for network messages any events or calls sent to it while it is in any state but "connected" get bounced off or queued. As a result the states themselves become very tightly coupled to the interface of the class they are controlling. Is this a bad approach? –  Ford Jul 23 '12 at 12:15
add comment

2 Answers

up vote 0 down vote accepted

This is a tough question to answer. A specific example of the problem you are experiencing would help to give better guidance. It sounds like you aren't splitting the responsibilities of your classes correctly so that a given class doesn't have too many dependencies. As a general rule, I try to avoid a single class having more than 3-4 dependencies. If you have classes that need a half dozen dependencies or more, I would try to split that class up.

I do agree with you that you should avoid eventing patterns unless you have a really good reason to use them. Using eventing to get around coupling and SRP issues doesn't seem like a good approach to me.

share|improve this answer
    
For example, I have a view system, controller system (as in MVC) and networking system, which all use state machines and have associated states for behavior (in the controller system a controller is just a specialized state) and some of the controller states themselves have state machines, because the behavior is pretty complex at times. Now if I want my controller state to be an observer of the view state I can just pass in that system, but what if I want my controller system to change state based on the state of the networking system (don't act on input when in a not-connected state)? –  Ford Jul 19 '12 at 12:41
    
Continued- In that case I have to make sure the controller system now gets references to two systems, passes those references to its controller state machine, and then into its own state machine if it has one. If I want to add more systems to this I have to change all this stuff every time, and have to be careful to manage registering and unregistering of observers properly. Then what if I want the controller to get information from the networking system for display on the view? I would have to add callbacks. It gets extremely complicated at this point. –  Ford Jul 19 '12 at 12:46
    
Even continued more- If I use an event system all I have to worry about is passing in a reference to it and registering/sending events. In that way classes with complex behavior are only responsible for sending/receiving events. –  Ford Jul 19 '12 at 12:50
    
It seems like you have your behavior organized in the wrong manner. Why would the controller depend on the state of the view? This is generally a code smell if you are trying to do MVC correctly. It sounds like you are not encapsulating behavior enough, and that every class needs to know "the business" of every other class. –  RationalGeek Jul 19 '12 at 19:11
add comment

If by 'responsibility' we equate 'reason to change' it depends on the granularity of the abstraction. Taking it to a ridiculous level, one might consider that because every method has its own responsibility there should only ever be one method per class but that's just crazy. I think that you're on the right lines with your Interface approach, but instead of injecting the dependencies into constructors you could see if DI/IoC framework or Service Locator pattern works in your scenario.

share|improve this answer
    
I've never used DI/IoC or the Service Locator pattern- do you think it would provide the layer of indirection I need? (see comments on the other answer) –  Ford Jul 19 '12 at 12:51
    
Potentially yes, but now after reading your comments I think perhaps the Mediator pattern is a better fit (google it). Be careful though, as jkohlhepp says, it sounds like your MVC implementation is a bit messed up - perhaps it shouldn't be MVC at all. –  Toby Couchman Jul 19 '12 at 20:52
add comment

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.