usable in any place a human can be used

20091221

impedance

[caption id="attachment_456" align="alignleft" width="300" caption="you can find really cool images searching for impedance mismatch, this one has lazers (with a z)"]you can find really cool images searching for impedance mismatch, this one has lazers (with a z)[/caption]

There is a threat to good software, one that threatens the most promising of software projects. This threat is impedance mismatch. I use impedence mismatch in the sense that Object-relational impedance mismatch uses the term, but make no mistake, I'm not talking about the difficulties of writing an ORM. What I wish to discuss is far more insidious, it is death by a thousand paper cuts, it can spell ruin for any project. Impedance mismatch is born out of the confusing first steps of a project, it can also arise from multiple developers working over time on a large project or from internal disagreements over the optimal solution.


The major problem is that when we go about designing some new piece of software, some whiz-bang solution, we do not fully understand the problem domain. Any good development team will spend days filling up whiteboards with the solution that models the problem domain, but anyone with experience will tell you that once you get into the guts of a problem you realize that things need to be changed. This is fine, in fact this is a sign that you are solving the actual problem and not the ideal one you began with, don't worry about changing your solution to meet the realities of the domain. The problem though is making these changes first class citizens and not some weird third class monster thrown into the mix.


Have you ever been on a project and heard a conversation like this?



New Developer: What is X?
Grizzled Veteran: X is what we refer to internally as Y
New Developer: Why do we call it Y internally but X on the UI
Grizzled Veteran: Time constraints... budgets.... other misc. bullshit
New Developer: *mental note: X is called Y sometimes*

BAMMO! There's some nasty impedance mismatch there. The problem is not so much in what we display to the user, or what our object properties are called, or what the database columns are named, the issue is that we have made our mental model convoluted. At the heart of all these systems we build as software developers is some sort of mental model, at runtime this is expressed in system as an object graph, for persistence it is expressed as a collection of tables and relationships, but all of these things are just a representation of some mental model.


[caption id="attachment_455" align="alignright" width="300" caption="artist depiction: working with an elegant mental model"]artist depiction: working with an elegant mental model[/caption]

When our mental model is internally consistent and simple and elegant, it makes life easy and happy and unicorns shoot out of our monitors and everything is sunshine and puppies. When your mental model gets convoluted it can be an awful and bewildering experience. The problem comes from an increased overhead, instead of the mapping from one representation to the next being clear-cut, the developer has to carry around a hashmap in their skull mapping various representations of their mental model. The difficulty of carrying out even trivial tasks is increased as the mapping from X -> Y -> Z -> Q -> P takes place.


[caption id="attachment_459" align="alignleft" width="200" caption="impedance mismatch vs. coupling: battle to the death"]impedance mismatch vs. coupling: battle to the death[/caption]

So let's just name everything the same and go home, problem solved. Oh, if it could only be so easy, the problem is that on the other end from impedance mismatch is a devilish little troll named coupling. Coupling is the amount that two pieces of software are intertwined, they could be tightly-coupled wherein changing one requires changing the other, or they can be loosely-coupled all the way to the point of being considered decoupled or orthogonal. Orthogonal pieces are nice to work with because you can change one and know that you won't have side-effects on other pieces. Orthogonality goes by some other names: encapsulation, modularity, and decoupled, it is generally considered a Good Thing© and I make no argument against it.


We now have these two seemingly opposing forces, we want to decrease impedance mismatch without introducing coupling, what should we do? There are many ways to deal with this issue, let's look at a few.


Adapters are nice little pieces of code (also called wrappers), that allow two different things to look the same. Let's assume we want to write some code to manage users, users have a name, an address, and an age. The developer of the class decides that this object can be pretty simple.


[php]
class User {
public $name;
public $address;
public $age;
}
[/php]

The database developer decides that he loves structured data and that this should be broken out into all kinds of columns and tables.


[sql]
table user (
user_id int autoincrement primary key,
first_name varchar,
last_name varchar,
addr_street varchar,
addr_number int,
addr_city int foreign key,
addr_zipcode int,
age int
)

table city (
city_id int autoincrement primary key,
city_name varchar,
state_id int foreign key,
)

table state (
state_id int autoincrement primary key,
state_name varchar,
state_abbrev varchar
)
[/sql]

We could create an adapter class that bridges the difference, for brevity's sake I won't include the code for it, but it would basically translate strings into database fields, as the application developer I get to imagine the database as mirroring my object, even though it doesn't.


ORM - ORM's are like automatic adapters. They are not without their faults and some implementations are better than others, but they mask the complexity of marshaling data and reduce the impedance mismatch.


Convention over Configuration - This was made famous by Ruby on Rails. There is some strong convention that you follow that allows for a consistent mapping between domains, an example would be that tables are always named the pluralized version of the class name.


There is no silver bullet to solving the problem of impedance mismatch, but a combination of the above can help limit it. The best thing you can do is be aware of the problem, don't introduce impedance where it is unnecessary, and never be afraid to ruthlessly refactor out impedance mismatch when you find it. Keeping impedance mismatch low increases developer productivity, lowers the bar for bringing on new people, and makes unicorns leap out of your monitor farting rainbows.

No comments:

Post a Comment