Imagine you are in control of a large company who specializes in building tools for developers. Your staff is full of developers with tool building expertise. They write lexers during lunch breaks and WYSIWYG designers on weekends.
Next, imagine someone asks you to select the perfect serialization format for your tools. Of course you’d pick XML, right? XML is easy to parse when you need to load data into your tool, and easy to create when your tool saves some output. Building tools with XML is like having your cake and eating it, too.
But wait, did anyone ask the customer if XML makes their job easier?
XML appears in everything from configuration files to form builders these days. In some scenarios XML is a good choice, but quite often developers have to read, write, and modify the XML created by tools, or we have to understand what a tool is producing, or we need to see the differences between two versions of the tool’s output to track down a bug in our software. None of these scenarios are pleasant to deal with. Tool vendors like to use XML because XML is convenient for the tools, but contrast this justification for XML against the design philosophy for Ruby put forth by Matz:
I hope to see Ruby help every programmer in the world to be productive, and to enjoy programming, and to be happy. That is the primary purpose of Ruby language.
When is the last time you felt productive and happy with XML?
Of course, the idea is to work only inside the tool and never look at the XML output. It’s easy to stay in a tool when a tool is a word processor, but developer tools are different.
Here are a few examples.
The first two versions of the Entity Framework used a visual designer to generate an .edmx file with all of the model metadata required for the Entity Framework to function. The .edmx file was an XML file. It was possible to do some work in the designer only to discover a build error during the next compiler run. A build error like the following:
Problem in Mapping Fragments starting at lines 6, 69: Non-Primary-Key column(s) CalendarID are being mapped in both fragments to different conceptual side properties - data inconsistency is possible because the corresponding conceptual side properties can be independently modified.
After you get past the initial shock of the foreign vocabulary being presented you’ll realize the error message is pointing you to lines of code inside the XML contents of the .edmx file. Woe to those who open the .edmx file with an XML editor and wade through the ocean of angle brackets. The entity data model inside the file requires more XML than you might expect if you’ve previously done any ORM mapping with XML files.
It was also possible, particularly in V1, to run into a scenario the entity data model designer didn’t support. To implement table-per-hierarchy inheritance, for example, required wading through several hundred lines of XML just to figure out the important bits that make the inheritance approach work.
Which leads us to the 5th and final lesson derived from the evolution of the Entity Framework:
When you sit down to design a software framework or tool, something you should keep in mind is the user experience. How will they interact with your software? How will they use your software to perform a job? What sort of jobs will the user need to do? Will they be happy, and productive, and enjoy programming?
There were a number of difficult aspects to the Entity Framework that all appear to derive from design decisions that benefited the Entity Framework instead of the customer. The non-standard connection strings, the lack of implicit lazy loading, the difficult API for working with object graphs, the visual designer that couldn’t scale up to model complex domains, and of course the mountains of XML, to name just a few.
In a future post we’ll take a more positive attitude and see how the more recent versions of the Entity Framework have addressed the 5 lessons we’ve looked at over this series of posts.