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.
3
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.
6
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.
2