usable in any place a human can be used

20091231

goals

[caption id="attachment_507" align="alignright" width="240" caption="you have to have goals..."]lifestyle's of the rich and famous motivational poster[/caption]

It's happened again, Jeremiah Peschka has called me out to write a blog post, well you smarmy bastard, here it is. The topic of this post is goals for 2010. Its the end of 2009 and so we have time to look back and reflect, we can also look forward and plan out the next 365 days.


Personal


These are the boring goals that don't have any computers or lasers in them, they are just things I want to accomplish for me.



  • New House - In March I will be moving into my first house with my wonderful girlfriend, Heather. I want to make this house a great place to unwind after a long day, a home filled with love, and, of course, include a badass office where I can program to my heart's content. This last part has been made much more of a reality by the recent gift from my awesome coworker, Carrie Frazier, of two giant whiteboards.

  • Health - I've been focusing a lot on interpersonal relationships and side projects in the last year which has left my once not too fat body in a condition Wii Fit calls Obese. It's been far too easy to pick up a pizza or take Heather out to eat and I have paid for it by becoming a much jigglier Matt. I plan on getting back to the healthy lifestyle I once had, and dropping some of this pizza weight.

  • Ink - Jeremiah mentioned this and so should I, it's been a few years since my last tattoo and I've had an idea for a good one for a while, I plan on getting it done at some point this year, sooner rather than later.


Coding


It's been a busy year and most of my life centers around putting fingers to keyboards trying to make something worthwhile.



  • Prosper - This is my baby that I've painstakingly carved out of php for the last few months. I think it is actually getting to the point where people could use it and not have their entire project fail, it's that good. I want to focus on improving the core of prosper, building the community, and promoting the crap out of it. The ball is rolling on having my awesome friend and fantastic designer Ashley Kruso make a new logo for prosper and at some point in the next year it will move to its own domain. I already have an upcoming event to talk about it (more details in a bit).

  • Blog - This blog started out as a free blogger account, then I moved it to my own domain (which you are currently at) and it runs off of WordPress. The design started off with the zDark WordPress theme which is now heavily modified. There are some things that I've just been too lazy about to change.


    • Better dark-on-light theme - I introduced the dark-on-light theme for people that had trouble reading the light-on-dark theme. It is very much a dirty hack, it does not retheme all the elements, and it is fairly ugly. I've had a better version cooking for some time but haven't had the drive to finish it up, I will strive to do so for the coming year.

    • Wider Columns - It's no longer 1994, we can make a fluid layout with bigger wider columns. The content column is less than 600 pixels, which is pretty absurd. I plan on reworking the layout to take advantage of larger screens while still supporting people living in 800x600 town.

    • Disqus - If you read yesterday's article you may have noticed that I ragged on Disqus as being bloated and ugly. Daniel Ha from Disqus was nice enough to drop a comment on that post and we had a very pleasant email conversation. Since this is still a feature people are asking for I will look into implementing it again, I also plan on producing a how-to for WordPress integration to document it and a review of the service.


  • Ruby - I've fallen in love a lot this year, lisp, smalltalk, and ruby have been my new technology sweethearts. I've been reading and finding ruby to be an acceptable lisp and actually a a not too bad smalltalk. Ruby, especially when coupled with rails, is something I plan on learning intimately and I hope to be able to provide some cool tools for that community.

  • Git - I've been an svn man for a long time now, but I have moved on to GitHub and have been learning the ins-and-outs of git. I am going to strive to really learn git and to work in it enough over the next year to feel as comfortable with it as I do with svn.


Business


As much fun as coding is, unless someone is paying for it you are going to get awfully hungry.



  • Black Projects - I have a few black projects that I'm working on on the side. One of which has, IMHO, great potential. Within the next year I hope to have one of these live in production and at least breaking even cash-flow wise.

  • Professional presence - See what I'm doing here typing at you, making an ass out of myself, this is called blogging. Blogging is a great way to increase your visibility and presence in the world. Now I'm not just, "That guy with the glasses who says weird things," I'm "That guy with the glasses who says weird things... on the internet." Big difference. I love blogging and I want to start giving talks in real life and become more active in user groups in the next year.

  • Relationships - This blog has already connected me to some of the nicest and smartest people I've ever met. I've been building some strong relationships and friendships, this isn't just good for business its good for one's spirit. I hope to continue this trend into the coming year.


Conclusion


This has been a fantastic year for me, first one in a while I won't be sending off with a "Goodbye Stink Town!" I'm looking forward to what 2010 will bring, if the movies of the 80's are right our jetpacks and hooker-bots aren't too far off.

20091230

minimalism

[caption id="attachment_493" align="alignright" width="296" caption="minimalist staircase... looks really dangerous"]minimalism[/caption]

I am a minimalist at heart, I like simple things with clean lines and no clutter. This is one of the reasons I love my new iMac, its just a beautiful magic floating screen filled with win. Minimalism is more than just an artistic movement or an ironically expensive interior design style. Programming is by its nature minimalistic, we programmers (as I have said before) are a lazy bunch. No one wants to type the same code over and over again, so we came up with functions, and then classes, and then inheritance, and frameworks, and aspect oriented programming, and so on and so forth. We want to reduce the amount of work that we as the developer has to do.


Here is a simple windows program that pops up a hello world screen using Visual C++


[cpp]
// GT_HelloWorldWin32.cpp
// compile with: /D_UNICODE /DUNICODE /DWIN32 /D_WINDOWS /c

#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>

// Global variables
static TCHAR szWindowClass[] = _T("win32app");
static TCHAR szTitle[] = _T("Win32 Guided Tour Application");

HINSTANCE hInst;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
WNDCLASSEX wcex;

wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_APPLICATION));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION));

if (!RegisterClassEx(&wcex)) {
MessageBox(NULL, _T("Call to RegisterClassEx failed!"), _T("Win32 Guided Tour"), NULL);
return 1;
}

hInst = hInstance; // Store instance handle in our global variable

HWND hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 100, NULL, NULL, hInstance, NULL);

if (!hWnd) {
MessageBox(NULL, _T("Call to CreateWindow failed!"), _T("Win32 Guided Tour"), NULL);
return 1;
}

ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);

MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
PAINTSTRUCT ps;
HDC hdc;
TCHAR greeting[] = _T("Hello, World!");
switch (message) {
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
TextOut(hdc, 5, 5, greeting, _tcslen(greeting));
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
}
return 0;
}
[/cpp]

Holy Shit! This is after I stipped all the comments, removed whitespace, and reformatted to 1TB. But here is how much code you need to do something similar in C++ leveraging Qt


[cpp]
#include <QtGui>

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QLabel label("Hello, world!");
label.show();
return app.exec();
}
[/cpp]

This is great news for the developer, we can accomplish the same result with much less code. We are now much more productive and so we have freed up some precious developer time that we can spend on something else. Our code is much smaller, much more minimalist now, which is good because we are lazy. This ends up being a dual edged sword because there is now the temptation to start coding up more features, because they are so easy to implement now. We have made our code more minimalist but in doing so have enabled developers to make their applications feature bloated and anything but minimalist.


Jeff Atwood wrote a post yesterday, Responsible Open Source Code Parenting, in which he asserts that John Gruber is being a negligent open source parent.



I don't mean this as a personal criticism. John's a fantastic writer and Markdown has a (mostly) solid specification, with a strong vision statement. But the fact that there has been no improvement whatsoever to the specification or reference implementation for five years is … kind of a problem.

The question I had, and still have is why. I wrote this comment on Hacker News yesterday regarding this post



The idea that since markdown hasn't done anything in years its somehow being stewarded improperly is a bit foolish. Look at Gruber's vision statement, he wanted to make an easy-to-read easy-to-write markup.

He did it, it is done, it's called markdown. If Atwood had his way Gruber would have spent the last 5 years filling it up with features and today we would be reading a post about how Markdown went from slim and sleek to fat and bloated.

Gruber set out to do something, then he did it, now it's done. It's a minimalist approach. Atwood would have rather he spent the last 5 years allowing for "open source collaboration" that would help in "moving forward and maturing" Markdown. To what ends?


It is easy to add feature after feature to something with the belief that you are somehow adding value, but the whole world doesn't think this way. Let's illuminate this with an example.












Apple Remote Windows MCE Remote

[caption id="attachment_496" align="alignnone" width="80" caption="There are 7 buttons"]apple remote[/caption]

[caption id="attachment_497" align="alignnone" width="245" caption="The technical term is an assload of buttons"]mce remote[/caption]


That's how the Apple Remote is intended to look, it's not lacking buttons because they haven't gotten around to putting some more on, they intentionally kept it simple. Now I'm not trying to argue that one remote is superior to the other, I prefer the Apple Remote, but the important word there is prefer. Atwood makes the mistake of thinking since something hasn't changed in 5 years its a problem. What if Gruber did the cost-benefit analysis of the new features for the last 5 years and decided that it just didn't need anything else.


People have asked me if I'm going to use Disqus and although I tried it for a bit I decided to just use the simple built-in commenting system. Disqus was all kinds of bells and whistles, it is (in my opinion, which since it's my blog is the only one that counts ;) ) ugly, and it's benefit doesn't outweigh it's cost in my opinion. By the time I took out all the stuff that made Disqus feel bloated to me I realized I basically had the simple built-in comments, just hosted by a third party, so I abandoned it.


There is a cost to every feature you throw into your software, the cost is added complexity. I have decided that complexity better come with some gain for the user, otherwise I won't add widgets and gadgets and features just to add them.

20091229

book review: design patterns in ruby

[caption id="attachment_62" align="alignright" width="226" caption="Go buy this now"]design patterns in ruby[/caption]

I am back from the holiday break and a perfect storm has come together, I'm currently working on a rails project, and I have a wonderful girlfriend who embraces my geekiness and buys me Design Patterns in Ruby. I have been reading this thing for the past few days and can't put it down, I wanted to read a chapter last night before bed, I sleepily set it down 5 chapters later.


Just so you understand something, although I love to read, I am a slow reader, books are hard for me to get through, I also have a ton of things to read and play around with, so you better keep my attention. I have also read the classic GoF book, so I'm coming into this book well versed in design patterns. I've played with ruby a few times before, but nothing too serious (if you look back in the archives you will see that my first post was on ruby koans).


Let's talk about this great book by Russ Olsen. The book does not require you to know anything about ruby, the first chapter is, in fact, a great primer to the language. Olsen comes from a background of 25 years of software development experience, as he puts it


I have been building software for more than 25 years. I’ve done assembly language, FORTRAN, Pascal, C, C++, Python, Java and now Ruby.
  -Russ Olsen

The introduction to ruby feels like it was written for someone with programming experience in a Java-like language. Throughout the book Olsen makes reference to the Java way to do things (which will be easy to grasp for the .Net crowd too). The primer to the language is interesting in that it skips some of the core things that makes ruby what it is (the whole meta-programming, monkey patching, message passing thing). This would seem like an oversight at first, but was helpful for me as a new ruby user. I wasn't bogged down in the different of ruby, so I could focus on the same. This let me feel comfortable with the language and focus on the patterns, as we will see, these parts missing in the primer will be fully explored later in the book.


The book is structured very much like the GoF book, with each chapter focusing on a particular pattern. Olsen opens up the chapter with some example situation, then he moves into how you could solve it with inheritance or ugly code. Then the problem is re-examined, a pattern starts to emerge, and then is described. The pattern is explained in the classic GoF style with example code (in ruby) and UML diagrams, the best part though is the clear, concise, approachable explanation provided by Olsen. The pattern now being firmly understood, the book digs into the pattern and looks at ways that we can ruby-ize it. At this point we are normally treated to some new interesting ruby language paradigm that let's us quickly and easily rewrite the pattern, making it more concise and elegant. There is then a discussion of the uses, and probably more importantly, the abuses of the pattern. Every chapter ends with a nice summary of what was learned and (as I found out last night) an enticement to keep reading as the next pattern is introduced.


[caption id="attachment_486" align="alignleft" width="240" caption="Pure unadulterated rocket sauce!"]rocket sauce[/caption]

The writing is incredibly approachable, Olsen does not get bogged down in technical jargon, he explains everything that's going on in a concise and understandable way. There are copious code examples that are excellent at providing a concrete example to the abstract pattern Olsen is discussing. The author mixes in some humor here and there and will show how other programming languages implement the patterns and historical reasoning for why things are the way they are in ruby.


The overall impression I got from this book is that it is win, condensed down into ink on paper. I have learned a ton about ruby, relearned some great patterns, and gotten a great insight on the ruby way to solve problems. If you find yourself thinking, "Well I don't need to learn design patterns, I'm so smart!" Well you are not, I'm going to use one of my favorite quotes here with a bit of a twist.


Those who don't understand design pattern are condemned to reinvent them, poorly.
  -Matt Nowack (original attribution to Henry Spencer)

Design Patterns are all around you, learning these will help you solve future problems, understand how rails works (in fact there are several occasions in the book where Olsen shows how rails uses this pattern or that one). This book is a pleasure to read, and I suspect will serve as a nice reference for implementing patterns correctly in ruby. I'm glad to have it in my toolbox, and I would suggest you get it for yourself.

20091228

modeling

[caption id="attachment_479" align="alignright" width="225" caption="Just like this, only less beautiful women and more boring data"]america's next top model[/caption]

When solving a problem the most difficult part should almost never be the implementation. Implementing a solution should be fairly straightforward from the solution itself, if it is not, then your solution is incomplete. That doesn't mean that you need to sit down with pen and paper and completely solve a problem before coding, this is an approach taken by some books attempting to teach software development. Some go as far to advocate for an even stricter approach, something along these lines.



  1. Model the problem domain with UML or some other modeling technique

  2. Translate your modeling into pseudo-code

  3. Translate pseudo-code into actual code

  4. Realize 2 month project took 2 years to complete

  5. Go to step 1 (the problem has radically changed since you took so long)


Of course, I'm poking fun at the books that take such a structured route. Here is a news flash for everyone Programmers are lazy. Here is another news flash (and this might actually be news to some people) Being lazy is good. Not all laziness is good, if it causes you to cut corners and fail to deliver a high quality product, than you fail at life. If however your laziness drives you to find an easier way to do things then "Lazy FTW!"


I have the "joy" of programming Java in my 9 to 5, when you write Java for a living you get used to the absurd amount of verbosity in your code, you also have the joy of Eclipse (notice no quotes around joy) that will write most of your Java code for you. Then there are things like Project Lombok that strive to make Java easier and more fun to write. C# got the memo, and let their programmers be lazy, let's take a look at attributes in a few languages


Here is some C# code to make a class called Foo with a string member called Bar that can be read and written
[csharp]
public class Foo {
public string Bar { get; set; }
}
[/csharp]

They realized people are lazy, let's look at the same thing in ruby


[ruby]
class Foo
attr_accessor :bar
end
[/ruby]

Again, concise and simple, let's look at some Java


[java]
public class Foo {
private string bar;

public string getBar() {
return this.bar;
}

public void setBar(string bar) {
this.bar = bar;
}
}
[/java]

Can you hear it? I can, it's the language architect saying "Just don't be so lazy, write those simple functions, it isn't hard." The truth of the matter is that it isn't hard, in fact Eclipse will happily write these functions for you, just hit CTRL-SHIFT-G. I'm sure there is a point here that I'm getting to, and here it is. I don't want to disparage Java or start a language war, what I want to point out is that Java has a different conceptual model than C# or ruby. C# has the concept of properties and ruby has the concept of attributes, Java doesn't have anything like this, classes have members and functions, nothing more.


The point is that the conceptual models your solution adopts will have huge ramifications on the implementation of the solution. There are many examples of unifying philosophies that make things simpler. Unix's concept that everything is a file, C++ concept of streams, Erlang's pervasive share-nothing message passing, ruby's duck typing. These are core concepts that have profound and far reaching consequences.


Working on a new side project I recently was struck by a way to simplify a complex data structure by adopting a new conceptual model. Creating an internally consistent, elegant conceptual model is the most important thing you can do for a project's success.


Conceptual modeling is a hard thing to get right, go into too much detail and your model becomes rigid and brittle, go into too little and the model can be impossible to implement correctly. Making a good conceptual model is like making a good analogy, there are a few hallmarks to a good conceptual model.



  • The conceptual model should simplify the problem domain. Files and folders greatly simplifies the concept of a hierarchical file system by relating it to something commonplace.

  • The conceptual model should not be overly complex to translate into an implementation

  • The conceptual model should be uniform and consistent, if you find parts of the problem domain falling outside the conceptual model or feeling "tacked on" you should rework the model


The next time a project seems stuck or overly complex, instead of refactoring code or attempting to throw another library at it, take a step back, look at the big picture and refactor your conceptual mode.

20091223

decompress

[caption id="attachment_472" align="alignnone" width="450" caption="Get ready for the feats of strength"]festivus card[/caption]

The holidays are upon us and no matter what holiday your particular sky god has you celebrate (Festivus for the Rest of Us!) there is one thread of humanity that binds us together at this time, days off from work. When you have some time off of work you can spend it doing any number of worthwhile things



  • Drinking egg nog until you black out

  • Eating your weight in sugar cookies

  • Having that same argument with your family that you've been having for the last 10 years

  • Watching 24 hours of A Christmas Story

  • Spending quality time with friends and loved ones

  • Living through the same day over and over and over, á la Groundhog's Day (Best saved for the actual Groundhog's Day)


If you are reading this blog there is a good chance that you are some sort of programming nerd, its ok, I don't care what the New York Times says. As a proud nerd you have probably heard of some sort of technology that interests you, maybe clojure has piqued your curiosity, or you finally want to learn that "rails" thing all those young whippersnappers keep talking about. I would argue that this can be a great way to decompress, if you do it right.


First off, find something different than what you are used to, if your 9-5 is .Net don't spend your precious free time learning more .Net, that's stupid. Go find something radically different, maybe look at a functional programming language, go find that weird kid in the corner and talk to him, he probably has interesting stories about fire. This might seem like a waste of time at first, but it's not. It's all too easy to get locked into an ecosystem, doing the same thing day in and day out, to get comfortable there and to start thinking that your way is the only way or the best way. Reading about other technology outside of your realm might not have a direct benefit to your 9-5, but you may gain a perspective or understanding that would be incredibly difficult to get from your standard frame of mind.


Second off, this isn't work, this is fun. You are allowed to make mistakes and change your mind. If you work through a tutorial or get done with the first chapter of something and find that you really don't care, then go find something else, the software world is full of interesting things. The thing is, only stop if you grok the subject and dislike it, don't necessarily stop just because you don't get it at first.


[caption id="attachment_475" align="alignright" width="300" caption="What? Caroling? No fuck that, I got some erlanging to do!"]erlang source in gedit[/caption]

Third off, this is just to whet your whistle. Don't ignore your loved ones, squirreled away with your Beginner's Guide to Erlang because you've fallen in love with the idea of massively parallel systems. Take this time to investigate several things, learning the basics and setting up your love affair for the next few months. Then make sure you tell the people you care about that you love them and eat too much food and do people things.


For me this break will be about Rails. I've followed rails for a while, I've always been impressed with it, and I've had a few false starts. I've gone through the Getting Started tutorial more than once. I'm a php guy at my core, but learning how other people do the web is worthwhile. I've started the adventure already and think that this time it might stick. I have a 2 hour car ride up to Cleveland and back that I plan to fill with listening to Rails podcasts.




That's all for now, go relax and decompress, that's what I plan on doing for the next 4 days. As a side note I will probably not update during the holiday break so if you obsessively check or your rss feed gets lonely don't worry I will be back on the 28th.

20091222

early present

[caption id="attachment_468" align="alignright" width="300" caption="open source software, the gift for everyone!"]pink present[/caption]

There is an early Christmas present for anyone using prosper, a new release, Version 0.7! You can get it hot off the GitHub or download here.


Version 0.7 has a lot of exciting new features, the biggest 2 were spurred on by Ian Potter and Jeremiah Peschka. The phpDoc has been updated (if you are still using version 0.6 you can find the old documentation here). The big news is that prosper uses Prepared Statements by default now, gracefully and transparently falling back to string interpolation where Prepared Statements are not available. The second new feature is the introduction of Explicit Transaction Management.


[php]
try {
Prosper\Query::begin();

//Do a bunch of stuff

Prosper\Query::commit();
} catch (Exception $e) {
Prosper\Query::rollback();
}
[/php]

Only some of the adapters support this, the ones that do not simply ignore the call to begin(), commit(), and rollback(). You can use the has_transactions() functions to check if the current adapter supports transactions.

































































































































Database Supported by Prosper Prepared Statements Transaction Support
dBase YES NO NO
DB++ NO NO NO
FrontBase YES NO YES
filePro NO NO NO
Firebird / Interbase YES YES YES
Informix YES NO NO
IBM DB2 YES YES YES
Ingres YES YES YES
MaxDB YES YES YES
Mongo NO NO NO
mSQL YES NO NO
MS-SQL YES NO NO
MySQL YES YES YES
OCI8 (Oracle) YES YES YES
Ovrimos YES YES YES
Paradox YES NO NO
PostgreSQL YES YES NO
SQLite YES NO NO
Sybase YES NO NO
Tokyo Tyrant NO NO NO

Happy Holidays, and Happy Coding!

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.