Whirlwinds of Code and Forming Design Patterns
One of the biggest issues with understanding object oriented programming is getting over its associated terminology. Most developers whether they realize it or not have formed design patterns, and use them all the time. If an established developer were to look at their code, they would often see that their application was broken down into data access and storage components, display components, and the logic that allows them to successfully communicate. When asked to bring a system from one application to another, they can usually do it with little to no modification. This is the idea behind design patterns.
In an interview yesterday I realized that I had better take a more aggressive look at design patterns. Understanding the terminology may be tough, but it is an excellent way to communicate an application's business needs, especially using UML, as well as getting down to the lowest level of describing the objects that will comprise your frameworks. I have always tried to get a firm handle on design patterns, but they have largely eluded me. I have understood simple systems like breaking your code into well defined model-view-controller layers, and using messaging to communicate between layers, but I have never really been able to understand the more advanced concepts. In the interview I noticed that I was designing with some object oriented concepts by using Fusebox, even if I didn't know what to call them, but ignoring some of the more specific ones.
Programming is often like the game Dark Cloud for the PlayStation 2. For those who haven't played the game, it is a role playing game in which the player travels around their world trying to re-assemble their world, which was scattered by an evil genie. The player is provided a weapon which is pretty weak to start with, and by travelling around the world, they can gain objects which make their weapon stronger. When they get enough objects, they can merge their objects permanently into the weapon, increasing its effectiveness. They then begin the process anew, adding objects to the newly enhanced weapon until they can merge it again. When you have better weaponry, the player can gain pieces of their world more quickly and can assemble more complex worlds in shorter time. It is like this with programming. Often I feel as though code is whirling around me and once I have that “aha!” moment it merges and becomes something solid for me that enables me to take the next step. Building large applications has caused me to develop different frameworks or APIs for me to use. For example, most of my applications require search, so I have developed a pretty thorough search framework, made up of components, that can be moved with little modification. I wouldn't have known that it was that, but it is.
Today, or last night rather, I had one of those “aha!” moments, the moments we all write software for. I was finally able to put names to some of what I was doing. Now that I am beginning to understand, I can see why it would be hard for experienced object oriented developers to explain to procedural developers how to do OO design. You just begin to think differently. I can see about ten areas in which I can improve my search API / framework to make it more portable. The hardest part is finding the dragon, slaying it is easy. In other words, associating design patterns to what you are doing is hard, once you can put names to faces so to speak, the rest is simple. For a while I could never understand why people were so excited about Microsoft enabling the use of C# in SQL Server 2005. But now I can see, you can create an entire data access framework all on the database server, abstracting the underlying database and its queries from the application. It would be possible, in a web application, to completely separate the model from the controller and view layers. This has huge benefits in code maintenance because you could have any number of applications using the data access framework through web services.
What really dragged it together for me was why Java was so tough. I realized that it was tough because my mostly procedural mind was trying to write a program thinking about what each class should do instead of things like what does this class know about itself, what is it's purpose. How do the methods inside it work to help it achieve its purpose. In short I was trying to write a simple program, instead of thinking about a toolset to help me achieve my goal. With Java, you have to diagram, you have to chart or you will just get lost. Even objective-c makes more sense, with over-riding the init method for objects. These things didn't make sense before, but now I am getting it. I still have a long way to go, but I think I'll start working with Mach II, even if there is a performance hit. That is a little more OO than Fusebox, but Fusebox is a great foundation for it.
All that being said, there are still some instances where you can go too far with data encapsulization. For example if you had a table that had contact information in it. You wouldn't want to return each row, create a struct out of it, then set an iterator method to go through each struct, then each element of the structs, at least not in ColdFusion. Iterating over a query is something that the built-in elements of ColdFusion do fairly well anyway so building frameworks to disassemble a query object, then re-assemble it as a bunch of structs is probably an un-necessary layer of complexity for most applications. So like anything else, discretion is required. Now I'm ready to tackle the UML book and hopefully figure out how to use that nifty ID3 tag reader framework for Objective-C that I downloaded a while back and couldn't quite figure out how to use. I've got Macintosh applications that need to be developed.