In December of 1998, I joined an Internet startup and dove into web development. This was also my first contact with Microsoft tools. I was a stranger in a strange land, having come from the world of embedded systems programming. Although I had written two Windows applications previously, I wrote the applications using Borland tools, and followed the Document-View architecture of Borland's OWL framework.
The startup put together a great team of hardcore C++ programmers, and we built a rich domain model. We didn't use the term "domain model" at the time, but a domain model it was, complete with a commercial, object-oriented database for persistence.
We chose to use classic ASP for the UI. To make our domain model available to ASP, we had to dress up our domain model in COM jewelry. COM provided the binary interoperability for ASP to call into our C++ middle tier. The artificial layer disturbed me and I wondered why we didn't write the entire application in C++. After all, there was this CGI / ISAPI approach we could use to avoid all the COM cruft. Thankfully, my thoughts along these lines never infected anyone else at the company.
Eventually, venture capitalists came along and told us we had to kick our object-oriented database into the street. If we wanted to support millions of users and roll like pigs in a sty full of cash, then we needed to use a scalable database like Oracle. With some homegrown code generation tools, we buried all the relational database cruft underneath our domain model (I've been a fan of code generation ever since). Again, we didn't think of our class hierarchy as a 'domain model', we all assumed this was how software was built. You keep the cruft outside the heart of your application, or the application runs the risk of infarction.
Over the next couple of years, we ripped through $60 million dollars in venture capital and joined a sock puppet in the Internet graveyard. I did some consulting and some video game work, and then ended up back in web development and the Microsoft world.
.NET was an exciting technology to me. The middle tier and presentation layer could use the same runtime, the same string type, and even the same language. No artificial cruft! There was even a clean data access API in the form of ADO.NET. If that sound's crazy, then try to understand my perspective. Based on the majority of my previous work, I expected the following from a software tools vendor:
In other words, I expect a generic tool for building the least common denominator of applications. Visual Studio is more than just a command line compiler - it provides all sorts of designers and wizards, too. I initially found these additions interesting. Then I realized the designers and wizards only make short work of creating an application, which misses the hardest part of software development.
One thing I've learned over the years is that writing the initial code for an application is easy. No matter how much you struggle with language syntax, or thrash around to find the magic incantations for a finicky API – the initial code is easy. At least relatively easy.
The hard part is coming back and changing the initial code. This is an area where many of the designers and wizards in Visual Studio fall flat, or lead developers in the wrong direction. For instance, the typed DataSet generator requires you to fill in all sorts of information about your data source, yet it doesn't detect simple schema changes that can break an application. The declarative data-binding features with embedded SQL commands make drag and drop development simple, but produce a brittle application that is resistant to change. Visual Studio seems headed in the wrong direction for enterprise developers.
When the inevitable changes come, the best weapons I've found to have in place are refactoring tools, unit tests, and a rich domain model. Refactoring tools help you make common changes to a code base, while one of the many benefits of unit tests is that they can ensure those changes didn't break expected functionality. The domain model / business layer is the heart of the application and is what differentiates each software project. Everyone has user interface code, data binding, and XML parsing. These are the easy parts to pick up and maintain from project to project. The business logic is unique, and deserves isolation and maximum clarity.
Visual Studio only provides a unit-testing framework in high level SKUs. Refactoring tools exist in Visual Studio, but are cumbersome. A rich domain model? Don't expect too much help from Visual Studio in this area. The good news is we might be getting closer in the future with an entity framework– or at least we can still hope.
Visual Studio is a far cry from the land of command line compilers, yet it's still far cry away from what we need for non-trivial applications. That's ok - we should never expect a single tool or environment to give us everything we need. Instead, we need to apply thinking, theory and design with a mix of the best tools available for the job at hand.
The good news is there are plenty of resources and tools available outside of Visual Studio. Here are some links to resources and tools I know. If you are only using Visual Studio today, I'm sure you can find something in the list to improve the maintainability of your application.