I have recently wrapped up building a simple CMS for Launch Marketing. I see some things that could be improved yet (see: When to Alphabetize), but the undertaking has been a success and I find that I cannot stop blogging of the project as I got to tackle some new challenges.
Something that is not new, which guided my hand, is a core principle at Headspring: Fight for the Center! I first heard these words in a chess lesson as a child, and the lesson in chess seems to apply to application design too. If you can control the center in chess you can control the whole of the board. If you can control the core of your application and keep the pieces at the edges from muddying up the center you are in good standing to keep the application stable and maintainable.
So what defines the core versus the "pieces at the edges?" Headspring's CIO Jeffrey Palermo underlines what the parts are and how to keep them loosely coupled in his blog postings on Onion Architecture. The core should hold the business logic and your objects while the UI and all of the external dependencies are detached into different Visual Studio Projects (Headspring is a .NET shop.). The core itself should not depend on other projects. Objects need to be something more than and something independent from gunk that bubbles up from the database as otherwise the whole of the app becomes tied to a specific hydration means making the implementation of the specific technology hard (impossible) to change out and the business logic tricky to both test and maintain given the way one thing bleeds into another.
I broke four external dependencies away from the core and UI in the name of keeping the application maintainable. They are the database, DateTime.Now, the sending of emails, and the writing of a sitemap XML file for the whole of the web app based on user-created "pages" within the CMS.
I toyed with the notion of somehow trying to detach the reading and writing of cookies from the rest of the UI too. I didn't do so (see: of both CMS routing and forcing browsers to close) and I'm not sure how I might have. I've done some Google searching today for anyone else who might have thought of this, but found nothing. I guess all of the web browser-related functionality stays in the UI project. It is healthy to ask one's self "What can I detach?" however, and I bring up the cookies as an example of posing this question. Per Headspring's CEO Dustin Wells: Question Everything...(within reason)
Regular Expressions are another example of something that is not an external dependency. I had no problem putting this in the core of my project as I know it will be maintainable even in the event of a port to another language:
using System.Text.RegularExpressions;
namespace AdministrableApplication.Core
{
public class EmailValidator
{
public static bool Check(string emailAddress)
{
if (Regex.IsMatch(emailAddress, @"^\w+([-+.']\w+)*@\w+([-+.']\w+)*\.\w+([-+.']\w+)*$"))
{
return true;
} else {
return false;
}
}
}
}
That said, one should be careful to not have too many different using statements sprinkled about the core. Such is a sign of external dependencies creeping in.
My UI still seems a little bulky as it has a lot of esoteric whistles and bells within it (see: easy AJAX?) and I wish more of the UI could have been legitimately jammed into the core. It is best to make the core as fat as possible.
Headspring recommends full system tests, but in this project I only wrote unit tests around the core of the app. While I don't recommend this as good practice, I will say in this case having only the core under test really pushed me to jam as much as possible into the core (see: Yay Tests!), and perhaps it is best to at least pretend that you are only testing the core of your app. If you knew that only the core of your application lay under tests wouldn't you try to secure as much as possible within the core keeping other Visual Studio Projects lean and minimalistic?
It's safest at the center.
Anyways, I hope you've enjoyed my chess analogy. It's your move.
credits roll, music begins: One Night In Bangkok
1 comment:
Nice post Tom.
Post a Comment