Saturday, July 09, 2011

My Work is Now Cut out for Me

Okay.  So I let myself get sidetracked on the development of my book as a result of having a lot to do at my current job.  That's the bad news.  The good news is that everything has been "percolating" during this time and I've come up with  a really good mental map of how I'm going to guide the reader through all the problems involved in agile database development.

Here it is...



Basically, the idea is as follows.

Goals:
We have the goal of increasing the speed with which value can be delivered by reducing the "bottleneck effect" that generally surrounds database changes.  However, we cannot do that at the expense of things we've already gotten good at; namely preserving the knowledge stored in a database and maintaining the availability of its service as experienced by a user via an intermediary application.

Obstacles:
There are risks posed to the things we are already good at by increasing the speed of change.  Changing structure, the way we do it now, implies risk to existing knowledge stored in a database.  It also introduces the chance that an application coupled to a database might not have had time to adapt to a change in structure by the time a change is rolled out.

There is also an obstacle to agile database development in that whatever infrastructure is required to mitigate the previously mentioned risks will probably not be available for legacy databases.

(From the Other Angle) Axioms:
Databases store knowledge - that is their primary role.  To acquire knowledge and make use of it, databases absorb and emit information.  Another thing to assume is that people will make mistakes.

Here's the big one: databases are objects.  They are objects that store knowledge on behalf of other entities, like applications.

In any environment, where there is risk or instability, test-driven development mitigates those dangers to the point of rendering them almost non-existent.  This is especially true in a good object-oriented environment where behaviors can be easily isolated and tested.

Solution:
Good object oriented platforms, and really even mediocre ones, provide the notion of a class.  That is: an encapsulated, refactorable unit of design that provides a reliable way to instantiate objects with predictable behavior and easy-to-couple-to interfaces.

Implementation:
We cannot simply take existing mechanisms for defining classes and apply them to databases because the forces around a database are different - they have "inertia" in the form of knowledge that cannot be lost in the course of a design change.

The core of the implementation is to introduce a predictable, highly structured create-or-upgrade path that minimizes errors, protects existing knowledge, and regulates how change is introduced to any given database instance.

The next step is to specify exactly how changes are introduced to a database by test-driving them.  This all-but-eliminates the chance that a database will lose knowledge in the course of changing its design.

Once that is accomplished, provide a strong interface for your database to ensure that application developers are warned of breaking changes as soon as they possibly can be.  You, yourself, can be warned of these changes by using test-driven development to specify the behavior of the current database.

Finally, there must be a way to handle errors.  This is a function of good database development practices - like taking regular backups - and providing a mechanism for rapidly introducing corrections to errors that have already been committed to production.  Once you have that system in place, by definition, you will have a process that can be used to enroll legacy databases into your agile database development process.

Friday, July 08, 2011

Where Does the Buck Stop?

So I just watched another Michael Moore propaganda film and the theme of individual non-accountability continues.

I have a question for anyone who is swayed to believe that homeowners are not responsible for the consequences of their actions or that workers aren't responsible for choosing to work a job where they are underpaid.

If individuals should not be accountable for the consequences of their actions, who should?

Tuesday, July 05, 2011

The Law of Damocles

People keep talking about the Law of Demeter.  It's a pretty good law - although it seems like a hard one to break in a modern programming environment.

Anyway, I'd like to propose another law based on a classical mythical character: The Law of Damocles: All code exists with a sword poised above its head.

Shit code is better deleted than mutated.  Ensure the behaviors are properly specified with tests, delete it, and start writing good code until the tests are all green again.

Sunday, June 19, 2011

The Golden Hammer

I think I've finally turned up something in my search for a compelling reason to use Ruby rather than something else. Here is the first argument in favor of it that includes an actual snippet of code that I have found:


I think people's insistence on Ruby being a worthwhile thing is based on its expressiveness when defining the behavior of an algorithm. Personally, I don't see how the Ruby code in that example is any more expressive than the C# code but that's not the point. For the sake of argument, I will grant that it somehow might be for some people.

It still doesn't matter. People are already able to write and understand very complex algorithms. Making them easier to implement is not a good thing. For one thing, it optimizes the easiest part of what we do. For another, it enables programmers with outdated skills sets by allowing them to do what they are comfortable doing: writing "programs" and wrapping them up in objects.

Defining algorithms is not what good programmers do. What good programmers to is encapsulate variation to such an extent that there is no need to define a complex algorithm. This is very difficult as it requires us to think about things in terms of entities with responsibilities rather than in terms of sequences of steps, some of which are conditionally executed.

So I think that Ruby is a bit of a golden hammer: It's optimized for how it looks rather than how it functions - it focuses on letting people indulge their bad habits rather than providing an incentive to correct their behaviors.

That is... unless there is some way it enables people to define abstractions and encapsulate variation better than other languages. If there is, please send me a link to an example demonstrating.

A compelling reason to learn Ruby, anyone?

I am presently in search of a clear, concise explanation of what advantage Ruby might provide over, say, C# or Java and rock-hard evidence to back up that(those) claim(s). Any suggestions?