How Far Do You Go with Decoupling?

I’m wondering where the line is drawn when it comes to decoupling objects within the core of a framework. I’m currently working on a Framework which will form the basis of a CMS and possibly an eCommerce application also, but while I understand the benefits of de-coupling and using dependency injection’, sometimes I think it makes more sense to avoid completely de-coupling core system components; those which make up the centre of a framework/system.

When you think about why you use dependency injection and why you decouple objects, it normally comes down to reasons of code clarity and re-use, but when working on code which will form the core of a system, these benefits aren’t really applicable, to the point that the increased level of verbosity hinders code clarity. As for code re-use, this just isn’t applicable in such circumstances - I mean, I just don’t see myself ever wanting to plugin the exception handler (as an example) from this project, into an entirely different project without changing a single line of code. If it were a unzipper, image processor, database connector, or any such thing, de-coupling makes a lot of sense, but completely de-coupling core code written specifically for a single project seems like more of a hindrance than a help.

I’m wondering where others draw the line, or if you de-couple absolutely everything, especially when it comes to static classes and methods, which can be really powerful, but which are difficult to use in the context of de-coupling. I guess the biggest problem I have isn’t necessarily with de-coupling core classes, but rather with making all classes completely independent of each other, relying solely on interfaces to provide type enforcement.

Can I get some opinions on this?

I think you’re asking a very impotant question.

Personally I try to utilize GRASP in my design as much as it is reasonable. I don’t decouple every bit of an application because for PHP web-applications it is an unnecessary overdesign. Core components may need decoupling, but not because you want to reuse them. There is another reason for it. If your components are not coupled, you may replace component with a newer version of it without changing all other code. In this case it is more about easing of code support than about code reuse.
So I think that you should decouple exception handler because when you design your framework, you just redirect all exceptions to log file. When you go production, you may need to email some exceptions. Or add error levels in the future.
I think the right way to go is think before decoupling - will you make any use of either reusing the created component or replacing the component preserving the interface and changing the internal logic.

From my own experience, I’d advice against designing your own framework, but rather doing a very good research of existing ones. I did the one a year ago and found Yii. It entirely follows what I consider the excellent design and if I wrote a framework, it would be very similar. But why reinvent the wheel?
I understand, that you may have some specific tasks and you really need your own framework. Then moveon and create the best one in the world :slight_smile: I just advice to study what’s already done before going your own way. That will save you lots of time and finally you’ll really create the masterpiece :slight_smile:

Good luck!

I decouple everything as much as possible, even for core framwork files. Why? because on different projects I may want a to use different front controllers on different projects (e.g one which handles localisation as per part of the request uri) while still using the rest of the framework.

A valid (imho) question here, is, should you replace all “$foo = new Foo;” lines with factories? This gives total decoupling… but at the cost of code clarity and verbosity along with poorer IDE integration.

I use factories for objects such as models and views, but for core, top level, framework files I initiate them directly.

Wardrop, maybe you should try TDD. It will tell you exactly how much to decouple.

In my experience, TDD helped me a lot in discovering the true responsibilities of
the components I wrote.

Amenthes, this is really excellent point!
But the problem with TDD is that before you can use it properly, you should learn it and practice it some time.

I decouple as much as I can, but when I am building a core framework that I will not be reusing small parts of, I tend to avoid decoupling in the core where it needs the most speed, as long as it is something relatively simple that can be decoupled if necessary in the future. PHP function calls are rather taxing- so I avoid repeated calls when possible when speed is absolutely necessary.

KJedi said:

From my own experience, I’d advice against designing your own framework, but rather doing a very good research of existing ones. I did the one a year ago and found Yii. It entirely follows what I consider the excellent design and if I wrote a framework, it would be very similar. But why reinvent the wheel?
I understand, that you may have some specific tasks and you really need your own framework. Then moveon and create the best one in the world I just advice to study what’s already done before going your own way. That will save you lots of time and finally you’ll really create the masterpiece

I have to say I agree with the second half of that, but not necessarily the first. Search for and study frameworks that can do what you need, but if you are an excellent programmer, chances are you will save time, frustration, and have a better result if you do “reinvent the wheel” for long-term projects. Not to mention all the knowledge and experience gained. MOST frameworks and libraries are excessively generic, and/or poorly programmed, and/or will ALMOST do everything you need, but not quite, and/or will have limited documentation that’s difficult to understand. Personally, I welcome the challenge of developing my own framework (and I’m a lot OCD), so I may be a little biased. I wish more excellent programmers would write their own frameworks instead of re-using all the other crooked, bent, and oddly shaped wheels out there just to save a little time.

Your post hints at an often ignored problem by OOP evangelists, and I’m glad you started this thread. My personal feeling is that there is indeed a line between trying to keep things decoupled and trying to keep things simple. Adding interfaces to everything and then depending on those interfaces sounds like the right solution at first (and sometimes is), but adding interfaces everywhere quickly puts you into Java territory. PHP is not Java.

A common solution is to instead rely on some kind of service locator/registry/factory/di container that you pass around that knows how to load dependencies. It does simplify things because there are less objects to pass around and all the dependencies are centralized, but it also comes at a cost because now your service locator object is itself a dependency throughout your application. There’s always a line you have to walk between keeping everything easy and simple and keeping everything fully decoupled.

As you gain more development experience, there are a few interesting solutions that seem to skirt around the problem of decoupling or at least minimize it, but they always come with caveats and trade-offs. You just have to decide which trade-offs you want to make.

I want to make my own framework for a couple of reasons. Firstly, the experience to be gained from creating your own planned and thought out framework I believe is important to truly understanding other frameworks and design decisions others have made in their systems. Another reason is that I like to approach problems from outside the common square of thinking. I haven’t really taken this approach in the past as I don’t think my PHP skills have ever been at a level which would allow me to do it, but I think I’m at that point now.

I do agree though that there are a lot of good frameworks out there, both simple and complex which have for the most part, done all the hard work for you. But until I make my own, and have that hands-on experience with planning, designing, writing and testing my own framework, I don’t think I’ll be able to distinguish the not-so-good framework from the really high quality ones.

Hi…

It’s the application components that have to be decoupled, not the framework core.

Imagine as many scenarios on how your framework will be used as you can. This will tell you which bits of the framework have to accept change. Which bits need to be swapped out. In other words you will find the flex points. Note you need a family of applications to do this. You can’t write a framework without this context. Applications are your users. You are left with the bits of your framework that will save time, the features, and bits of framework that must accept change, the flex points.

All the code you’ll ever write is either for a feature or a flex point.

Flex points are harder than features. Because they have to accept a range of features, they are harder to code. They are also harder for the passer by to understand, and you need more documentation too. This means you have to choose your flex points even more carefully than your features.

Once you have your scenarios and your flex points, you’ll have some idea which flex points are esoteric and which are really useful. Triage them as you would a feature list.

If it’s not a flex point, hard code it and be happy :).

yours, Marcus