CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Dave Laribee

"Whoso would be a man must be a nonconformist." - Ralph Waldo Emerson
  • OMG Rake!

    Rake is just... lovely. There's no other way to describe it. I just moved our XEVA Framework to rake and ended up with this build script weighing in at only 35 lines:

    Check out the :harvest task where I'm requiring an external file that's contains code for bundling up the various build outputs, currently just .dll and .pdb files. The file looks like this:

    I'm in love with Rake -- and the idea of executable configuration in general -- for a few reasons:

    1) I can take my scripts down to a reasonable size. The NAnt script for this simple build weighed in at a hefty 162 lines. These two files combined hover around 65. That's much better signal to noise and it only gets better with the more complex scripts.

    2) I can make new tasks lickity split. With ruby you just write some code inside a task. It's easy to leverage popular libraries like Hpricot for XML poking and peeking and such. No need to compile tasks and manage separate projects just for build code.

    3) I can see what's happening! Ruby is a very flexible language. I can use it's tricks to pimp out my build scripts and I don't need to sift through angle bracket madness. Note how I opened up the Dir class to define a new method, exists?. Ah the joys of ruby. We can make things somewhat familiar to our .NET teams while keeping it idiomatic. With tools like IronRuby this prospect get's even juicier.

    Getting Started

    If you're just getting started with rake, you need ruby first. The "one click install" at the official Ruby site is what I'm using and it's a pain-free setup. There's plenty on Google, but I recommend giving the Rails Envy boys a click for a super-basic-but-effective primer. Remember the sh method is your friend and, when in doubt, RTFM!

  • Introducing Kanban at Xclaim

    We've rolled out Kanban at my company Xclaim Software. Prior to this we were following a more-or-less XP process evolved and tweaked over some two years.

    Xclaim Kanban 1.0

    Even though our team has been doing the Agile thing with good results, there are times that the process seems a little opaque and wasteful. I've noticed that it's hard to surface where we're encountering bottlenecks or impediments. Planning and maintaining a large inventory of backlog creates waste; planning can take several hours for large batches of new stories and, while I think there's good value in preparing a as-full-as-possible backlog at the beginning of a project, I see very little value in maintaining a backlog over three months at a maximum. There's simply too much risk of redundancy and re-work in a large backlog.

    For a while now I've seen iterations as an arbitrary nuisance. We all know velocity is a yardstick measure that's imprecise and best used for rough planning. We can also take points delievered over any two points of time and compare this number to previous durations to develop a trendline. Over a longer history we can use these numbers as a measure of throughput and improvement. Why then do we need to make them reset every Wednesday? If we're using similarly-sized items -- which we are -- it seems that feature cycle time (time from 'activation' to 'in production') is equally useful and much more understandable by both customer and developer.

    A big source of waste, waste due to over-processing, is the planning, retrospective, and customer demo ceremonies. It's easy to burn a half-day or more in these meetings and the fact of the matter is that a lot of these things can just be JIT'd on an as needed basis with the right people getting us much closer to the lean concept of pull.

    Is it too much of a stretch to say project determines process? Every project we work on and environment we work in will come with requirements that drive a customized process. Of course we can't get there from day one. We need to setup a good baseline with the practices we know have broad applicability, acceptance, and tolerance: TDD, rolling wave planning, etc. Good Agile teams, however, continually adjust their process to fit their product and the needs of their customers. In a sense, we're designing our process as we go and this is something I see Kanban encouraging.

    There's a few things to say about this Kanban thing we've got going on, and I'd like to tackle this as a mini-series to make the posts digestible. I'll continue with five installments to start:

    1. Why bother? Pull, flow, throughput and constraints.
    2. Anatomy: queues, buffers, work-in-process, standard work and order points.
    3. Developing and introducing a Kanban in your team.
    4. A tour of our initial Kanban pipeline.
    5. Handling rework and the zero defect mindset.
    6. TBD

    If you're interested in Kanban, I highly recommend subscribing to the Yahoo! Group. You may also want to check out Corey Ladas' blog; he writes about the practice with some regularity, sharing valuable insight and experience.

  • Migratory Compromises

    Martin Fowler recently wrote an article about incremental data migration. In it he covers some of the pitfalls to putting off data migration and the benefits associated with tackling migration iteratively. As a lot of us are doing re-writes or replacement systems in this day and age it's worth a read.

    I think there's an important piece either implicit to the piece or missing. Namely: when we put off migration we might be exposing ourselves to the possibility a large net decrease in the quality and/or functionality of the new system. I'll explain.

    When we're developing new systems we're often correcting the errors of our own making or an inherited past. We are hopefully ensuring the integrity of our new data structures whether they're produced as a side-effect of an object system or domain modeling effort or we're making some kind of database as a primary project artifact. So can we assume that existing (and scarily dirty) data can be brought over into this new, pristine environment? Clearly the answer is "no."

    Often times we're working with legacy data from a rat's nest system that's evolved over the years. I remember a particular nasty data migration that, postponed to the end of the project, took a good month to do. Not just a month of effort, a month of toil and drudgery!

    Indulge me a brief war story. The data in question was from a system that had been through several data migrations and patched/in-place replacements. First Sybase, then Access, then SQL Server 6. There were several tables of questionable value, "day of week" and "gender" immediately springing to mind. One could look at rows as kinds of geological strata. Certain fields became out of date and screens ended up being coded with conditional logic along the lines of "if the record date is less than a certain day, get this semantic value from this field, otherwise..." As if this wasn't enough there were out-and-out data integrity errors of the particularly egregious nature. There was no way the reports siphoning this data could be correct or counted on. At best they were a relative and probabilistic measure of what was really happening the business.

    Naturally I made the mistake of not taking this albatross into account. Nightmare.

    What can you do to avoid this situation? As Martin shares, making an initial assessment of the current data structure would be a big first step. If the data is messy, you'd be well served to tackle migration incrementally and early. But what about my (maybe not so) extreme case where data "assets" are in awful shape?

    Conscript Users

    If you have the luxury of leveraging users to fix data issues, use it. Sometimes these issues can be fixed through the legacy application itself. For example, we introduced a feature in our vendor management module that ensures vendors aren't duplicated (by their tax ID). In a client's system there was all kinds of redundant data. We approached them with this issue and worked out a plan of collapsing duplication before counting on migrated data.

    Defensive Architecture

    Sometimes it's best to raise your guard against imported data in your application's design. By taking an early assessment (which, in the case of product development, might be an educated guess) we can decided if old data is trustworthy. If not, we might build our applications in such a way that missing or invalid data is part of the app itself. Taking the vendor de-duplication example, we might have built a feature that let users correct duplication in the new system and just brought the data over as is. Expanding on that feature, we might also have prevented 1099s (tax forms) from being generated for suspected duplicates providing an exception report for these cases.

    The problem with designing for bad data is the increased effort -- and therefore cost -- involved in design, implementation, and test. This strategy, I'd say, should be used as a last resort and sparingly. All disclaimers aside, sometimes it can't be avoided; we can all probably tell a data horror story or two.

    The Real Risk

    We've been cruising on this new project. We're happy with the design and it's an order-of-magnitude better than the previous solution. Our client's going to be thrilled! That's a lovely feeling to be sure, but in reality what we're bringing forward might be a limiting factor in total success. You might have to make disappointing compromises like scrubbing new features or extending a project's scope/time/budget if you've developed a feature that simply isn't compliant with old data.

    A thorough initial assessment paired with incremental migration can help you make Agile decisions about architecture and client involvement. Without techniques like this you'll essentially be rolling the dice on how long migration takes or, at the worst case, whether new features are practical without a whole slew of compensating or enabling features.

  • Deep Fried DDD

    Over the weekend I got the chance to sit down with Keith Elder and Chris Woodruff of Deep Fried Bytes fame and discuss domain-driven design. It was a fun conversation and the first part (of two) is available for download.

    We focused on some of -- what I'd consider, anyway -- the important fundamentals of DDD: ubiquitous language, bounded contexts, and model driven development. I'm happy with that outcome; I feel too many times people new to domain model and DDD latch on to some of the less critical concepts (the repository pattern, say) when they should be asking: "what's this do for me and at a 10,000 foot view how should I structure my models?" Part 2 of the podcast will delve more into the nuts and bolts of the core pattern language: entities, value objects, repositories, etc.

    So if you're new to DDD* or working on domain models, check it out!

    Now back to your regularly-scheduled programming...

    * And if you're new to DDD you really should read Eric Evans' book!

  • Rik on Design Patterns

    Rik Bardrof, one of the senior developers at Xclaim, recently gave a presentation to the Syracuse .NET Developer's Group. I was in town, so I captured the talk.

    In it, he covers a few patterns/principles we use extensively in our products:

    Enjoy!

  • Doctors We Ain't

    Time for a little bit of a rant.

    In a recent post, Jeffery Palermo paraphrases an analogy made by David Platt on a recent episode of the .NET Rocks podcast:

    In software, we can't expect our clients to know what they need. Much like the depth of a patient may be "I need to get rid of this infection" or "Give me some pills. I'm in pain". Our clients know what is causing them pain, in the business sense, so the problem is from that experience perspective. Some clients might go so far as to ask for some "pills", that is, they might ask for a specific software system that is assumed to solve the problem.

    I have to disagree.

    There was a time where I would agree with this statement, but implementing practices such as a weekly demo, an acceptance testing environment, and user stories actually written by the user drives my issue with the notion that software developers and architects have all the answers.

    Users Definitely Know What They Want

    It's not like user's don't know what they want; they do. Damn straight stakeholders know what benefit they expect from a software engagement. When they don't we're practically cruising toward an unsuccessful outcome where the inmates (developers) are running the asylum. They know how their business works better than you do. They likely don't know how to get what they want. If the purport to, then you probably have a problem on your hands. In my experience, this is rare.

    The Domain Expert

    And what about the method Domain-Driven Design puts forward? A domain expert -- often a user of the software -- is the best resource for understanding complex business logic. They'll tell you the what and we figure out the how. Of course with a practices like model-driven development (where model == code), DSLs, and BDD we're bringing our code ever closer to the user.

    If you don't have a domain expert or your expert is unwilling to spend time with you, that's a risk in your project. You'll see the doctor analog, but I'd caution bringing that template in as a norm. It's a risk and a sub-optimal situation. Fight for your right to talk to the domain expert! Build a relationship there.

    The ToC Approach to Software

    Eli Goldratt discusses the role of software initiatives in a lean organization in a presentation available on Audible. One of the processes in ToC is the 4x4 event. In short, the 4x4 is a meeting involving business leaders where constraints and conflicts are identified. It's a time used to identify problems with the system as a whole. One possible result of this meeting is to launch a development project that provides the minimum possible product to exploit and/or protect a capacity-constrained resource. Think the folks putting money down know what we want there? You betcha.

    So What Are We?!

    In one respect we're cartographers. We're there to take the business need and convert that to working code, ideally on a regular basis. In another light, especially in product development, we're stewards or politicians. It's our job to take multiple inputs from multiple customers and introduce features in a way that satisfies our constituencies. The big risk in this context is, of course, re-election.

    A doctor-patient relationship is a very particular pattern of human behavior. How many of you have been rushed through a doctor's visit or had the "privilege" of a visit with a hot-shot specialist? I know last time I was in the hospital (for a wrist surgery, RSI) I spent about four hours waiting around.

    I'd advocate a more collaborative approach. Users do know what they want. Developers need to raise their game to collaborate with them to show them how to pull product. We can start by taking some time and showing them how to write a user stories, for example. We want to establish a relationship with the users of the software we make (their software!), walk a mile in their shoes, and expend the effort to better communicate by forming a peer relationship.

  • How I Got Started in Software

    My buddy Jason Meridith tagged me in the blog meme du jour asking, "how did you get started in software development?"

    How old were you when you started programming?

    At the age of ten or so I frittered around with Basic on the Commodore 64 and Vic-20 back in the day, but I wouldn't classify that as anything too serious. I was a big fan of text-based adventures and they were pretty easy to make. The real art/challenge/fun was always in the story and design of the puzzles. Thankfully, I missed the punch card era.

    How did you get started in programming?

    I really got hooked in college. Now I went to your typical north east liberal arts college and studied eastern religion and psychology (predominately), but one day I made friends with a wacky fellow who called himself "Lothar" and he turned me on to MOOs. MOOs are kind of like a MUD but marginally less geeky. It's essentialy an online community backed by an object oriented programming language. One thing lead to another and I became a programmer on a MOO.

    What was your first language?

    The MOO language (apparently Algol-like) and Pascal in college. In production terms a schizophrenic mix of FoxPro and C.

    What was the first real program you wrote?

    A program that calculated when an oil tank needed to be filled based on tank volume, average daily temperatures, furnace type, and the date of last fill: what a perfect scenario for DDD!

    What languages have you used since you started programming?

    C#, Ruby, JavaScript, Visual Basic, Java, C, C++, FoxPro, SQL, Pascal, and MOO.

    What was your first professional programming gig?

    I started working full time in software at the age of 20. I was hired to write an application for a personal GPS-tracking device. There was some embedded development to do but the main thrust of the application was a call center tool that would record and plot the devices on a map. Fun. As this was a start-up, I also wrote a number of one off applications to hedge starvation. My favorites clients were the ones that would give you free stuff: a cheese shop and a beer distributor.

    If you knew then what you know now, would you have started programming?

    Without a doubt, yes.

    If there is one thing you learned along the way that you would tell new developers, what would it be?

    Two things actually:

    1. Focus on principles. Don't get hung up on products, rather form the opinions and learn the techniques you'll be able to transport with you across any project. It's the kind of investment in your self that pays dividends to you and your clients, so win-win.

    2. Connect with other developers. You'll encounter the "Simpson's Comic Shop Owner" personality as you do this, but ignore them and persist until you find a group of peers. The learning that will come from this group (and it's usually a symbiotic relationship) is incredibly valuable.

  • Super Models, Part 2: Avoid Mutators

    A quick disclaimer: we're entering religious territory here. I feel strongly about this issue, but it's certainly my opinion. If you want to get the full sense of how passionate people are about this issue, check out this article at JavaWorld.

    I've come to the point of view that Entities should not use set mutators ("setters"). Anything you represent as a setter can usually be better represented as a plain old method. Why?

    Let's remember one of the fundamental guidelines of DDD: intention revealing interfaces. Which is more intention revealing?

    Customer c = new Customers().Find(42);
    
    // This...
    c.Address = aNewAddressValueObject;
    
    // or this?
    c.ChangeAddress(aNewAddressValueObject);
    

    That's a subtle point and it's admittedly open for debate. To firm up my argument let's consider the situation where I'm crunching knowledge into model and address change becomes a temporal concept. I now need to track what an address is of a certain date and time. Surely a setter will do the trick, but I think the command "change an address" is better expressed with a method. I can fiddle with the internals of that method and, because we're practicing command-query separation, accept that commands change the state of aggregate roots and entities.

    For me, the biggest argument for avoiding setters is that it promotes thinking in terms of data in a paradigm (DDD) where data-first can be harmful and counter productive. I cannot stress enough: entities are behavioral objects and, for my money, Action<T> where T is some value object fits the notion of command rather elegantly.

  • "Agile Shop"

    The term just reeks of steady state management.

    I find the idea of an "Agile shop" or an "Agile team" is a little misleading and misses the point. What we want is an "Agile organization." The main feature of Agility, to me, is the ability to respond to change: to follow new business opportunities or address challenges. This feature has nothing to do with software development. It just so happens that software might be required to exploit business potential.

    No doubt you can employ development practices such as TDD/BDD, DDD, continuous integration, etc. (after quite a steep learning curve and dues paying process) to create an Agile codebase, but we should not convince ourselves that this is what it means to work in an Agile shop. Good practices simply indicate we're striving for quality and maintainability and collective code ownership and a good team.

    There are more important limiting factors. Let's look at our backlog (or in lean terms, investment): Is it prepared? Do stories have acceptance language? Is there an expression of business value? Is software being released or demonstrated regularly. Is there involvement? Are there clear and evolving priorities? Are your stories speculative things written by the development team or a lead or an architect? And have you been developing infrastructure code in an "Agile way" for the last two months? Do customers/users refuse to meet with you? Is work constantly being expedited? Are you in a cube farm? Do you work a ton of voluntary overtime and is there a turnover problem in your team?

    In the realm of continuous improvement certifications and labels don't count for a whole heck of a lot. Even the most deadly clan of XP ninja will create a local optima rule that is likely to damage the entire system (i.e. company). Businesses need to consider larger issues of throughput (sales) and constraints. Which shareholders care if the team's rocking when there's a mountain of work in progress piling up at deployment preventing new revenue? Which line manager's responsibility is it to make sure the right things are being worked on? How are decisions being made in the larger context?

    Not to get super preachy on you all, but sometimes I think we're full bore on the wrong mission.

  • Crunchy Peanut Butter

    In a post where Jeremy drops some fluent fu, he responds to my assertion that Windsor and NHibernate are the peanut butter and jelly of ALT.NET:

    I'll overlook the fact that my friend David also implicitly implied that an IoC container not named StructureMap was the de facto standard.

    Okay. Okay! Fair enough. Let's call StructureMap the "crunchy peanut butter" (my favorite) and Windsor the "smooth peanut butter" and Ninject the "organic peanut butter" and Unity the "peanut flavored soy-based food paste used on human-powered NASA missions, a.k.a. 'Astronaut Peanut Butter'." Sorry, Glenn, you're name came up when I asked who I needed to alienate next.

    I guess if this post had a point it'd be that our peanut butter is really the Dependency Inversion Principle and the jelly is the paradigm of OOP/DDD/etc. Good reminder!

  • Test Your NHibernate Mappings!

    Disclaimer! Ayende rightly points out that if you are testing your queries you get this mapping test for free. If you aren't, well put this in place as a stop gap measure (to test mappings) and if you have queries, which you probably do, get to testin'!

    A while back Bil Simser put up a post on the first test you should write when using Castle Windsor. In it he shows a technique for verifying his component registrations are correct.

    Since Windsor and NHibernate are the peanut butter and jelly of the ALT.NET crowd, I think we can and should do the same for NHibernate:

    
    [Test]
    public void Verify_NHibernate_mappings()
    {
       string myConfigPath = @"wherever\you\put\your\NHibernate\config.xml";
       Configuration config = new Configuration();
       _sessionFactory = config.Configure(nhibernateConfig).BuildSessionFactory();
    }
    
    

    Would that I did this before today. Yeah, I win the douchey team member award for making a bunch of refactorings (renames mostly) and not fixing the mappings. Remember: Resharper, as great as it is, doesn't do NHibernate mappings. Of course the unit tests passed so I think I'm fine and move on with my life. The next developer that updates with my commit can't run the app and gets to clean up my mess. Fun for them!

    I've learned my lesson. This little screw up illustrates the need for at least some automated integration tests and the lynchpins of many of our architectures -- the ORM/IoC tools -- seem like easy and high value targets.

  • Hook Methods

    I've written about the template method pattern before. For my money it's still a very useful pattern for building super lightweight frameworks and enabling the open-closed principle which states:

    Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.

    So let's review quickly what a template method looks like and what it can do for our code:

    
    public abstract class PriceCalculator
    {
      public Money Calculate(Product product)
      {
        Money retailPrice = GetRetailPrice();
        Discount discount = CalculateDiscount(product);
        return discount.Apply(retailPrice);
      }
      
      public abstract Discount CalculateDiscount(Product product);
      
      public Rate GetRetailPrice() { //... }
    }
    
    public class GoldCustomerPriceCalculator : PriceCalculator
    {
      public override Discount CalculateDiscount(Product product)
      {
        // Gold customers get 20% off, OR
        // We could use per-product discounts.
        return new Discount(20); 
      }
    } 
    
    public class StandardCustomerPriceCalculator : PriceCalculator
    {
      public override Discount CalculateDiscount(Product product)
      {
        // Standard customers receive no discount
        return new Discount(0); 
      }
    }
    
    

    It's pretty easy to see we've gotten some variation. This is a simple example off the top of my head and there's probably a better way to tackle this domain problem, but it shows template method in action so I'll leave it alone.

    This is all well and good, but what if we encountered a scenario where our class could function autonomously but we want to provide an hook or extensibility point for edge cases or later extension (beware of YAGNI on the latter). I'll call this technique a hook method.

    What's a hook method? By playing with the physics of template method a bit to we can make derivations elective by lifting the abstract constraint on our base class and making the template method virtual. The former move is optional and the later is required. Your solution will dictate whether or not the base class should or should not be declared abstract.

    Let's consider an example where we want a start/finish semantic for an implementation of model view presenter. In this example I want to have a base presenter that provides some common functionality: attaching the presenter to the view and raising events to signify the presenter has been started. I want to provide a hook so my presenter implementations can do some processing, call services, obtain reference data, etc. I can accomplish this with a hook method style of template method like so:

    
    public abstract class Presenter : IPresenter
    {
    
      public void Start()
      {
        if (Starting != null) Starting(this, EventArgs.Empty);
        View.Attach(this);
        Startup();
        if (Started != null) Started(this, EventArgs.Empty);
      }
      
      protected virtual void Startup() {};
      
      public event EventHandler Starting;
      public event EventHandler Started;
    }
    
    

    Or we can return to the contrived example of the price calculator to illustrate a non-abstract class:

    
    public class PriceCalculator
    {
      public Money Calculate(Product product)
      {
        Money retailPrice = GetRetailPrice();
        Discount discount = CalculateDiscount(product);
        return discount.Apply(retailPrice);
      }
      
      public virtual Discount CalculateDiscount(Product product)
      {
        return new Discount(0);
      }
      
      public Rate GetRetailPrice() { //... }
    }
    
    public class GoldCustomerPriceCalculator : PriceCalculator
    {
      public override Discount CalculateDiscount(Product product)
      {
        // Gold customers get 20% off, OR
        // We could use per-product discounts.
        return new Discount(20); 
      }
    }
    
    Money price = new PriceCalculator.Calculate(someProduct);
    // or
    Money price = new GoldCutomerPriceCalculator.Calculate(someProduct);
    
    

    I'm sure many of you have seen examples of this in the wild. I'd file this under "pattern life hack." That is, a simple and subtle shift in thinking around template method that expands its many uses in DRYing up your codebase.

  • Super Models, Part 1: Sexy Specifications

    In Domain-Driven Design we turn to the specification pattern when we want to check whether an object matches some criteria. I think specification is the oft-forgotten bastard child pattern of the domain model pattern language. I know I frequently turn to queries -- sometimes query objects -- when I want to retrieve a set of some entity to work on.

    There are some major drawbacks to using queries. Namely there's a huge testing liability. Say we're using a technology like LINQ or NHibernate HQL or even SQL. Well our query and its various predicates that make up our "where clause" are tied up in a single monolithic statement, each of which needs testing. We end up reach deep into the bucket of compromise to find solutions to deal with this mess. Things like object mothers and fluent fixtures help, but are in no way ideal. Wouldn't it be great if we could create a little vocabulary where each word was verified and tested?

    Well, yes, it would. And we can accomplish some of these goals by breeding the specification pattern with one of the original GoF patterns, composite. Other people have written about or demonstrated this concept (extensively) so I'll keep my treatment lean and referential, but I'd encourage you to read on; I'll cover a cute little trick at the end.

    Sidebar: Specification is quickly challenging service or component for the title "most overloaded term in software development." Think about it; we've got specifications in Behavior-Driven Development, Domain-Driven Design, and Design by Contract. To be clear I'm using specification in terms of model specifications and the practice of DDD.

    Composite Specifications

    Let's start with a quick interface, and I'm assuming you've done the background reading on the pattern:

    public interface ISpecification
    {
       bool Matches(T entity);
    }
    

    In reality I'd use a generic with a constraint to be sure that "T" in our case is an IEntity. I define an IEntity for my models so I can be sure we have things like an "ID" and a "Version" and can safely but generic constraints in layer supertypes like repositories, builders, factories, etc.

    Next I'll define a base class, or layer supertype if you trend fancy, with some special methods and some nested classes. Pay attention to the "And" and "Or" with corresponding nested classes:

    public abstract class Specification : ISpecification
    {
       public abstract bool Matches(T entity);
    
       public Specification And(ISpecification specification)
       {
          return new AndSpecification(this, specification);
       }
    
       public Specification Or(ISpecification specification)
       {
          return new OrSpecification(this, specification);
       }
    
       private class AndSpecification : Specification
       {
          private readonly ISpecification left;
          private readonly ISpecification right;
          public AndSpecification(ISpecification left, ISpecification right)
          {
             this.left = left;
             this.right = right;
          }
          public override bool Matches(T entity)
          {
             return (left.Matches(entity) && right.Matches(entity));
          }
       }
    
       private class OrSpecification : Specification
       {
          private readonly ISpecification left;
          private readonly ISpecification right;
          public OrSpecification(ISpecification left, ISpecification right)
          {
             this.left = left;
             this.right = right;
          }
          public override bool Matches(T entity)
          {
             return (left.Matches(entity) || right.Matches(entity));
          }
       }
    }
    

    And I suppose we'll make a sample entity and a couple specifications. These are admittedly very anemic (setters are usually work of the devil) and contrived. It's illustrative folks!

    public class Customer
    {
       public decimal TotalOrders { get; set; }
       public bool Active { get; set; }
    }
    
    public class StatusSpecification : Specification
    {
       private readonly bool active;
       internal StatusSpecification(bool active)
       {
          this.active = active;
       }
       public override bool Matches(Customer entity)
       {
          return entity.Active == active;
       }
    }
    
    public class TotalOrdersSpecification : Specification
    {
       private readonly decimal amount;
       internal TotalOrdersSpecification(decimal amount)
       {
          this.amount = amount;
       }
       public override bool Matches(Customer entity)
       {
          return (entity.TotalOrders > amount);
       }
    }
    

    With all this in place I can now chain specifications together to achieve a composite -- if not somewhat awkward and noisy -- syntax. Example? Okay, sure:

    var specification = 
       new TotalOrdersSpecification(42m).And(new StatusSpecification(true));
    
    var customer1 = new Customer() { Active = false, TotalOrders = 41m};
    Console.WriteLine(specification.Matches(customer1));
    // False
    
    var customer2 = new Customer() { Active = true, TotalOrders = 43m};
    Console.WriteLine(specification.Matches(customer2));
    // True
    Console.ReadLine();
    

    Bring the Hotness

    Update Nigel Sampson describes a similar technique using lamdas and operator overloading. It's a slightly different spin on the same problem, but he also uses the operator overloading trick for clarity. I'd encourage you to check it out; his blog is new but there's some good stuff there already.

    I have some issues with the syntax immediately above. Namely we've got a pretty limited means of expressing complex orders of operation in our specifications. If, in pursuit of complex expressions, we pull the AndSpecification and OrSpecification out then we get an even noisier syntax:

    var specification = 
        new AndSpecification(..., ...).Or(...);
    

    I think I can do better. If we're pursuing the DDD goal of "the model is the code" and we're trying to bring our model to evermore expressive heights we need to eliminate some of the parenthesis junk. We can do this by using that most magical (and dangerous) feature of C#, operator overloading.

    Let's send my specification base class to wardrobe and makeup, stat!

    public abstract class SexySpecification : ISpecification
    {
       public abstract bool Matches(T entity);
    
       private class AndSpecification : SexySpecification
       {
          private readonly ISpecification left;
          private readonly ISpecification right;
          public AndSpecification(ISpecification left, ISpecification right)
          {
             this.left = left;
             this.right = right;
          }
          public bool Matches(T entity)
          {
             return (left.Matches(entity) && right.Matches(entity));
          }
       }
    
       private class OrSpecification : SexySpecification
       {
          private readonly ISpecification left;
          private readonly ISpecification right;
          public OrSpecification(ISpecification left, ISpecification right)
          {
             this.left = left;
             this.right = right;
          }
          public override bool Matches(T entity)
          {
             return (left.Matches(entity) || right.Matches(entity));
          }
       }
    
       private class NotSpecification : SexySpecification
       {
          private readonly ISpecification specification;
          public NotSpecification(ISpecification specification)
          {
             this.specification = specification;
          }
          public override bool Matches(T entity)
          {
             return !(specification.Matches(entity));
          }
       }
    
       public static SexySpecification operator &(SexySpecification left, ISpecification right)
       {
          return new AndSpecification(left, right);
       }
    
       public static SexySpecification operator |(SexySpecification left, ISpecification right)
       {
          return new OrSpecification(left, right);
       }
    
       public static SexySpecification operator !(SexySpecification specification)
       {
          return new NotSpecification(specification);
       }
    }
    

    Now we have a much more natural and terse syntax. You have to use the & and | operators because you can't overload binary operators such as && and ||. I'm OK with this; I get less line noise:

    var specification = 
       new TotalOrdersSpecification(42m) & new StatusSpecification(true);
    

    Admittedly it's a little thing, but as we move into more complex composite specifications little differences like these really start to reduce the mental tax associated with parsing a model which, to me, is a big, big deal. And, when all is said and done, isn't it the little things in life that really matter?

  • Entity Framework: Our Albatross

    Looks like another Entity Framework barfight! Hell, I'll join the fray started by Jeremy. I feel compelled given that I'm part of the NHibernate Mafia.

    Ah! Well a-day! What evil looks
    Had I from old and young!
    Instead of the cross, the Albatross
    About my neck was hung.

    The Entity Framework is the Albatross of ALT.NET. We're forever doomed in podcasts (two I've been on have devolved into this rat hole), blogs, and twitter to have to rail against the machine that is the EF. Let's work toward an elevator pitch, explain why we won't use it, don't believe it will work, and get the hell on with our lives.

    I remember being in Redmond at the original meeting. Yes it's true that this is the genesis of all this ALT.NET business, but come on! There's more to it than NHibernate vs. EF, but we keep coming back to this same, tired subject.

    I made an observation that EF (back then "LINQ to Entities") isn't an ORM way, way back:

    ...EDM (Entity Data Model) is a logical representation of a data model. The framework will permit various “services” to be attached to this model such as domain objects/models containing behavior (which is what we want to test and test-drive after all) replete with LINQ queries, reports, mock and test data generation, entity aggregation type service endpoints, etc.

    Ah... the youthful exuberance of past me (March, 2007). Clearly this is very initial analysis on a beta of a beta of a beta, which is to say: not very deep. I'll admit it. But there's an initial flame of recognition in there.

    An ORM can't be a mere facility to a "data platform." Platforms are old school, we're buckling under the weight of cumbersome frameworks and the myriad scaffolding needed to get an app running on a platform. The Java folks are headed toward MicroKernel architectures and we see this evolution starting in the lightweight containers that tend to germinate as IoC tools. Pick your flavor. So now we're talking platform?! Why on earth would we start with bloat?

    Furthermore and perhaps more immediately, Jimmy Bogard hits the bell with a sledge hammer:

    I think it's a mistake to share a data model with anyone outside your bounded context (see Evans, Domain-Driven Design). It's also a mistake to share a conceptual model or a EDM or whatever we're calling this.

    This is an enterprise architect's vision. All that time enterprise architects are thinking about the single platform to rule them all, well they should consider more how their production lines (e.g. teams in a lean sense) are organized and how to achieve flow, pull, leveling, etc.

    Silver bullets are, in fact, an illusion. We learned this long ago. Let's refresh our memories and move on.

    Okay?

  • Design: Paul Rand & Ubiquitous Language

    The Ubiquitous Language is an important concept in Domain-Driven Design. Some time back, I found this video of Paul Rand talking about his views on the essence of design and art. I love it and see an immediate parallel between his thoughts and the style of language oriented design a good modeler strives toward.

    Consider this quote right from the opening:

    When you say design, everybody has a definition which doesn't coorespond to yours... there are many good definitions: one is the synthesis of form and content. In other words without content there's no form. So without form there's no content. A work of art is realized when form and content are indistinguishable. When form predominates meaning is blunted, but when content predominates interests lag. But the genius comes in when both of these things fuse.

    Wow; that bit directly expresses my approach to and concept of successful software design.

More Posts Next page »

Our Sponsors

Free Tech Publications