object oriented programming, encapsulation and the command pattern
First you will have to excuse me for last week, while it is my intention to write at least one blog post a week, real life and more specifically a current project at my job have had me tied up quite a bit I’m afraid.
Also in the interested of actually writing about something people would want to read, I am paying special attention to the popularity of my blog posts. Since at the moment I have only 4 posts and about roughly the same amount of visitors, I can hardly make any real conclusions from that data. However even with numbers as low as those, it seems my blog post about object oriented programming is by far the most popular. This could be skewed for many reasons, but for the moment I will assume it is true. If any of the four people whom read this blog would like me to address some other topic, then please do use the comments and I will see what I can tell about the subject.
Now with all that said, it will come to no surprise that I will try to explain a little bit about object oriented programming. Specifically, as the title already betrays, about encapsulation and the command pattern. Now I know I already briefly touched on that topic in my previous blog about OOP and patterns, but I just like it and it is my blog.
So what is encapsulation, and why should you care?
Encapsulation is, as the word describes, the idea that functionality and data should be encapsulated within its own domain. This, at least in my eyes, is the single most important and single most beneficial aspect of object oriented programming. In a way it even defines what object oriented actually is.
A object is a representation of a distinct entity of your program, which encapsulates its behaviour. Thereby abstracting the functionality and making it easier to work with and think about.
Now that is all well and fine, but why would I want to encapsulate, you ask,? Well depending on your level of experience with existing code the answer should already be painfully clear. Just think back about that project that was built years ago, which kept getting more feature requests until the initial functional design in no way represented the project as it is now. Such projects often suffer from bad encapsulation, different parts that intertwine way too much with each other. Making it expensive in time to add/remove or even modify features.
That is exactly what encapsulation fights. By correctly encapsulating behaviour you guarantee that none of the encapsulated functionality is touched upon elsewhere in the project. You effectively limit the domain it has effect upon.
Many if not all design patterns embrace the idea of encapsulation but I think the command pattern does so in the most direct way. The command pattern as I explained in a previous blog post encapsulates a piece of functionality exposing only a common method to call it, this is useful in many ways. Think for instance about “actions” that need to be executed or as a specific example the image manipulations from my previous blog. I could have put knowledge about those things in the object that handled the images as collection. That however would have meant that that object now, not only has to know about the images, but also about how to manipulate them. That may sound minor, but in reality that would in fact give a single object two responsibilities. Now while I do not have direct proof, I can guarantee you that however elegant it might initially be written over time the object would get encumbered with even more functionality for manipulating images.
However if the manipulation of images is in fact fully encapsulated within a separate object that bears the responsibility to do just that one action, we force ourselves to keep that functionality within that object. Meaning that however much we might change the way those images are manipulated we will never need to touch the object that controls the collection of images. We could for instance easily switch from using GDlib to libMagick. The only thing we would need to do is modify the command objects and perhaps their parent object which might contain shared functionality.
You might even imagine we could keep both these versions and detect up-front what modules are available to us and choose which set of command objects to use, depending on that. If we had not used the command pattern it would not be unthinkable that this choice would also have ended up in the object that initially only held the images, thus creating the start of the wild growth that would eventually lead to a super sized object that might hold half of the project functionality.
Disabled comments because I was only getting spam. If you want to comment just do so on another article and add that it was actually for this one and i’ll move it or something.