Monday, December 1, 2008

Aha

I was working on a problem the other day. I was following my own best practices

- think critically
- think first
- avoid implementation while thinking
- think maintainability

I was trying to figure out the best way to solve a problem. I had given it a good initial analysis, but i was also dealing with a deadline, so i was feeling pressure to get to implementation. I gave in to this pressure, against my better judgement, and was 2 or 3 hrs into implementing a solution. The solution had me adding knowledge of one service into another via our coldspring container (which in itself is fine) and then using the new service in the old one to do a lookup of a bean to get a value that would determine which of two methods to call in a gateway. All the while, i was feeling like i was missing something easier. I just had that feeling that my solution was too complicated for what i was trying to do.

The problem in a high level nutshell was this: i had certain records in an association table that i sometimes wanted to be included in the return set of a look up, depending on where it was being called from. There were some records that i did not want included other times. It wasn't until the third day that i had been looking at this problem that i saw what i was really trying to do, which was simply to ignore certain records in the association table ALL THE TIME. I just did not see this at first. I actually opened the association table and was looking at the columns in the table talking out load through the problem when i saw the simple solution. I knew in about 10 seconds that this was the better solution.

I checked out of our repository the files that i had already updated, i think there was 3, and started back at point A with my new solution, which from a code standpoint was one single line of SQL in one function that omitted the records when a field was set to 0.

My solution was in the DB, not the code. I ended up simply adding a bit field to the table, setting it to 1 (default value for all records) since all but about 100 of the 7000 records in the table would remain in play and changing the records that i did NOT want in play to 1. Then added the line to the function that conditionally omitted the recs set to 1.

The trade off is a check on this new bit field for every look up to the table and the need to update each new record that falls into the value = 1 category. The gain is a simple, maintainable solution with little to know memory overhead.

Analysis, heavy thinking, database, software architecture

Last week was a big conference for some of my clients. Naturally, there was a fluerry of activity leading up to the conference. My customers made specific requests about some features in our flagship application that needed attention. I was reminded of the following points.

1 - Trust your design. If you have a MVC design in place, trust that it will pay dividens when you are up against timeline constraints.

2 - Break the requests down into little pieces, as much as possible. Do not look at all the requests at once. It would have been easy to get a little overwhelmed at the requests given the time constraints, rather than being overwhelmed, beak it down and trust.

3 - Communicate in very clear terms. Spell out exactly what you are understanding to your customer. I asserted to my customer what i though was asked for and they asserted back ubtil we had that cleared up.

4 - Back to point 3, Requirements are at least 1/2 the battle. My customers dont give me black and white requirements, they explain what they want, but i need to help them clarify the specifics. This is where a front to back design methodology is very valuable. A picture is worth a lot. Show the client what they are asking for - it will help inform what they are trying to say.

5 - Go to a quite place to think through the problem. Noise is a great enemy of critical thinking. I was reminded of the inverse pyramid too. When push came to shove, i was the only one who could make most of the changes being requested. Thats good and bad, good for job security, bad for organization. Picture a pyramid, now flip it upside down. At the top there is lots of room, many hands involved - clarifying the requirements, building prototypes, documenting, testing, as you move down the pyramid toward implenentation, the bottom, fewer people are involved, as your reach the very bottom, there is only one person holding everything up. This is not a statement of pride, no - rather an observation.

6 - Heavy lifting - Trust that you will see a good solution to the problem. Resist the urge to implement the first solutions that pop into your head. There is always a better idea. I like to stay on a problem for a couple days, at least two, where i can give it my best brain power. Almost, without fail, after the second day, i see a better solution that what i had at the end of the first day. Think through the problem. The more time the better.

7 - If the update involves a heavily travled or common path in your application, then think REALLY hard about what you are doing. One of the updates i made to the application was to a very public object. The initital solution i saw added too much overhead to that object. The second solution i saw after a third day of analysis was much lighter. Lighter in terms of less trips to the database.

8 - Think in terms of tradeoffs - this is a mantra that i hear a lot of smart developers saying. Everying you do is a tradeoff. If you persist a piece of data via bean, in memory - saving a trip to the DB, the tradeoff is a bit more overhead. If you keep the overhead real lean, the tradeoff is more trips to the DB. If you choose to keep lookup code in your view page for simplicity, the tradeoff is less maintainable and reusable code. If you choose to follow a mature design pattern and layer your code in a MCV pattern, for ease of maintenance and troubleshooting, the tradeoff is a bit more complexity.

9 - Document your decisions - Someone once said code your documentation. That may be a little overkill, but the point is made. Think about someone else maintaining the code you are writing / updating. Add relevent comment to the code itself. I also like to add information around the bus. logic decision that i am making. I will admit, that i am making these decisions in a vaccum, so its important to document why i made decisions the way i did. 6 months down the road, when i have to update that area of the application again, im always thankful.