Breaking Down Design Patterns: Creational Patterns
At first it seemed like a huge waste of time to create very simple objects that would be aggregated into a more complex object for use in an application. I kept thinking that it was better just to create the object, when I was in procedural mode, and use it as I would. If I needed something else based on that object, I would just copy the code over into the new object and keep plugging away. But that was until I started being confronted with 2000 line long classes that had been worked and reworked over the course of a year until they were almost unintelligible.
There is some point at which procedural code, or in web parlance, every-page-is-an-island, programming gets beyond an individual's ability to understand, or remember everything happening in that code. I was reading a blog where someone said that for them it was around 10k lines. I'd wager that it varies by the programmer, but there is always a point.
In modern business, applications are frequently combined with other applications, specifications shift dramatically from alpha to beta to production versions, and then sometimes will shift after release. It isn't what is ideal, but it is the state of business.
In these cases it is important to design your database and your application initially taking into consideration how changes can affect your ability to deliver updates in a timely fashion. Making your database more entity driven instead of being row-and-column driven will help. In addition, diagramming your classes and methods before designing your database will allow you to create a more flexible database which will make maintenance of the application as a whole many times easier.
Probably the best way to keep an application simple is to avoid massive conditional statements and instead break each function of a complicated function down into its tiniest increments. Then build objects based on this. This is what creational patterns are designed to do. Allow you to use your small objects to create complex objects and keep the re-usability of your objects. If you wanted to create a library of code, it wouldn't serve you very well to create very specific data access objects. It would be much better to create more entity driven objects. For example, an address data access object may consist of a street address, a zipcode, a city, and a state. Assuming it is a US street address, but you could fairly easily write a decorator class to extend the address object to accept international addresses.
The address object may know about the person that is attached to that address, or it could be a company. Therefore it would make sense to combine an address object with a person object, and both of those, perhaps with a company object to create an entire entity for one type of program. Perhaps for another program, you only need the person and the address, not the company. No problem, create a new factory object that will create an entity without the company object. Most programs will use some kind of address object, so it makes sense to make it more generalized, perhaps accepting the table as an argument. It would be logical to normalize your field names with another object, or provide a readme to tell yourself the next time what field names to use for that object. This is how you can create a highly reusable object library that will make building other object oriented applications a snap.
That is pretty much the reason to design software this way. The other reason is that when there is an issue in your software, you don't have to comb through thousands of lines of code, you can locate the class that is responsible for the specific behavior that you are having difficulty with, and, assuming you have a solid unit test for that object, figure out what is wrong with it. Since it is a simple object, it should be relatively easy for you to fix it and get your application back on track.