Sunday, April 10, 2011

Smelly mixins

Just recently I had to do some work on a good old LAMP stack. Yes, PHP coding.  Only a quick fix, so I will not dwell upon it, but it got me thinking about something I haven’t thought about for a while. Includes. The kind of include statements that pulls a body of text (e.i. code) into another body of text.
PHP has them; ASP and JSP have them as well.

This kind of include statements can obviously lead to very smelly code as the resulting “file” might become very long and you might not notice things like clashing names, or that part of an include is completely irrelevant in one context but crucial in another.

In the scripted languages mentioned earlier, these include statement is one tool to reuse code, reduce duplication and keeping the size of individual files small enough to work with. But applying this technique in other languages where you have a whole other set of options to keep chunks of code focused and reusable will result in in something really smelly.

You can achieve the same kind of include mechanism with Ruby modules and Objective-C categories; but when used as a way of splitting up what otherwise would be a large class, it is likely that you have lots of duplication in the included files and that there is a high coupling between individual include files. It will most likely also make it hard to follow basic rules like method-should-do-one-thing and having methods with a single level of abstraction in them.
Why? Because you are likely to have naming clashes as you are only working on a very small piece of what is essentially a very large class, with too many responsibilities.





So, should you stop using these constructs? Absolutely not!
All though Ruby modules and Objective-C categories share some similarities they are not equivalent.
They are both a way of adding behavior to other classes. In Ruby it can be a class that is unknown at the time of writing. In Objective-C you target a specific class that you do not have access to (e.g. a class provided by a library).
The constructs are a great tool when used with this purpose. But when they are just used to split a large class, they are only perfume sprayed on you code smell.

No comments:

Post a Comment