Contents tagged with DDD

  • Side Effecting Functions Are Code Smells Revisited

    After talking with Greg Young for a little this morning, I realized I missed a few points that I think need to be covered as well when it comes to side effecting functions are code smells.  In the previous post, I talked about side effect free functions and Design by Contract (DbC) features in regards to Domain Driven Design.  Of course I had to throw the requisite Spec# plug as well for how it handles DbC features in C#.

    Intention Revealing Interfaces

    Let's step back a little bit form the discussion we had earlier.  Let's talk about good design for a second.  How many times have you seen a method and had no idea what it did or that it went ahead and called 15 other things that you didn't expect?  At that point, most people would take out .NET Reflector (a Godsend BTW) and dig through the code to see the internals.  One of the examples of the violators was the ASP.NET Page lifecycle when I first started learning it.  Init versus Load versus PreLoad wasn't really exact about what happened where, and most people have learned to hate it.

    In the Domain Driven Design world, we have the Intention Revealing Interface.  What this means is that we need to name our classes, methods, properties, events, etc to describe their effect and purpose.  And as well, we should use the ubiquitous language of the domain to name them appropriately.  This allows other team members to be able to infer what that method is doing without having to dig in with such tools as Reflector to see what it is actually doing.  In our public interfaces, abstract classes and so on, we need to specify the rules and the relationships.  To me, this comes back again to DbC.  This allows us to not only specify the name in the ubiquitous language, but the behaviors as well.

    Command-Query Separation (CQS)

    Dr. Bertrand Meyer, the man behind Eiffel and the author of Object-oriented Software Construction, introduced a concept called Command-Query Separation.  It states that we should break our functionality into two categories:

    • Commands - Methods that perform an action or change the state of the system should not return a value.
    • Queries - Return a result and do not change the state of the system (aka side effect free)

    Of course this isn't a 100% rule, but it's still a good one to follow.  Let's look at a simple code example of a good command.  This is simplified of course.  But what we're doing is side effecting the number of items in the cart. 

    public class ShoppingCart
    {
        public void AddItemToCart(Item item)
        {
            // Add item to cart
        }
    }

    Should we use Spec# to do this, we could also check our invariants as well, but also to ensure that the number of items in our cart has increased by 1.

    public class ShoppingCart
    {
        public void AddItemToCart(Item item)
            ensures ItemsInCart == old(ItemsInCart) + 1;
        {
            // Add item to cart
        }
    }

    So, once again, it's very intention revealing at this point that I'm going to side effect the system and add more items to the cart.  Like I said before, it's a simplified example, but it's a very powerful concept.  And then we could talk about queries.  Let's have a simple method on a cost calculation service that takes in a customer and the item and calculates.

    public class CostCalculatorService
    {
        public double CalculateCost(Customer c, Item i)
        {
            double cost = 0.0d;
           
            // Calculate cost
           
            return cost;
        }
    }

    What I'm not going to be doing in this example is modifying the customer, nor the item.  Therefore, if I'm using Spec#, then I could mark this method as being [Pure].  And that's a good thing.

    The one thing that I would hold an exception for is fluent builders.  Martin Fowler lays out an excellent case for them here.  Not only would we be side effecting the system, but we're also returning a value (the builder itself).  So, the rule is not a hard and fast one, but always good to observe.  Let's take a look at a builder which violates this rule.

    public class CustomerBuilder
    {
        private string firstName;

        public static CustomerBuilder New { get { return new CustomerBuilder(); } }
       
        public CustomerBuilder WithFirstName(string firstName)
        {
            this.firstName = firstName;
            return this;
        }

        // More code goes here
    }

    To wrap things up, things are not always fast rules and always come with the "It Depends", but the usual rule is that you can't go wrong with CQS.

    Wrapping It Up

    These rules are quite simple for revealing the true intent of your application while using the domain's ubiquitous language.  As with anything in our field, it always comes with a big fat "It Depends", but applying the rules as much as you can is definitely to your advantage.  These are simple, yet often overlooked scenarios when we design our applications, yet are the fundamentals.

    kick it on DotNetKicks.com

  • Side Effecting Functions are Code Smells

    I know the title might catch a few people off guard, but let me explain.  Side effecting functions, for the most part, are code smells.  This is a very important concept in Domain Driven Design (DDD) that's often overlooked.  For those who are deep in DDD, this should sound rather familiar.  And in the end, I think Spec# and some Design by Contract (DbC) constructs can mitigate this, or you can go the functional route as well.

    What Is A Side Effect?

    When you think of the word side effect in most languages, you tend to think of any unintended consequence.  Instead, what we mean by it is having any effect on the system from an outside force.  What do I mean by that?  Well, think of these scenarios, reading and writing to a database, reading or writing to the console, or even modifying the state of your current object.  Haskell and other functional languages take a pretty dim view of side effects, hence why they are not allowed, unless through monads.  F# also takes this stance, as "variables" are immutable unless otherwise specified.

    Why Is It A Smell?

    Well, let's look at it this way.  Most of our operations call other operations which call even more operations.  This deep nesting is then created.  From this deep nesting, it becomes quite difficult to predict the behaviors and consequences of calling all of those nested operations.  You, the developer might not have intended for all of those operations to occur because A modified B modified C modified D.  Without any safe form of abstraction, it's pretty hard to test as well.  Imagine that any mock objects that you create would have to suddenly know in 5 levels deep that it is modified in some function.  Not necessarily the best thing to do.

    Also, when it comes to multi-threaded processing, this becomes even more of an issue.  If multiple threads have a reference to the same mutable object, and one thread changes something on the reference, then all other threads were just side effected.  This may not be something that you'd want to do.  Then again, if working on shared memory applications, that might be.  But, for the most part, the unpredictability of it can be a bad thing.

    Let's take a quick example of a side effecting an object like implementation of a 2 dimensional Point.  We're going to go ahead and allow ourselves to add another Point to the system.

    public class Point2D
    {
        public double X { get; set; }

        public double Y { get; set; }

        public void Add(Size2D other)
        {
            X += other.Height;
            Y += other.Width;
        }
    }

    public class Size2D
    {
        public double Height { get; set; }

        public double Width { get; set; }
    }

    What's wrong with the above sample is that I just side effected the X, and Y.  Why is this bad?  Well, like I said, most objects like these are fire and forget.  Anyone who had a reference to this Point now has a side effected one, that they might not have wanted.  Instead, I should probably focus on retrieving a new one at this point, since this is pretty much a value object.

    What Can You Do About It?

    Operations that return results without side effects are considered to be pure functions.   These pure functions when called any number of times will return the same result given the same parameters time and time again.  Pure functions are much easier to unit test and overall a pretty low risk.

    There are several approaches to being able to fix the above samples.  First, you can keep your modifiers and queries separated.  Make sure you keep the methods that make changes to your object separate from those that return your domain data.  Perform those queries and associated calculations in methods that don't change your object state in any way.  So, think of a method that calculates price and then another method that actually sets the price on the particular object. 

    Secondly, you could also just not modify the object at all.  Instead, you could return a value object that is created as an answer to a calculation or a query.  Since value objects are immutable, you can feel free to hand them off and forget about them, unlike entities which are entirely mutable.  Let's take the above example of the Coordinate and switch it around.  Think of the DateTime structure.  When you want to add x number of minutes, do you side effect the DateTime, or do you get a new one?  The answer is, you get a new one?  Why, well, because it's a structure, and they are immutable, but not only that, it solves a lot of those side effecting problems.

    public class Point2D
    {      
        private readonly double x;
        private readonly double y;
       
        public Point2D() {}
       
        public Point2D(double x, double y)
        {
            this.x = x;
            this.y = y;
        }

        public double X { get { return x; } }
       
        public double Y { get { return y; } }
       
        public Point2D Add(Size2D other)
        {
            double newX = x + other.Height;
            double newY = y + other.Width;
           
            return new Point2D(newX, newY);
        }
    }

    Spec# is a tool that can help in this matter.  Previously I stated why Spec# matters, well, let's get into more detail why.  We can mark our side effect free methods as being pure with the [Pure] attribute.  This allows the system to verify that indeed we are not side-effecting the system, and any time I call that with the same parameters, I will get the same result.  It's an extra insurance policy that makes it well known to the caller that I'm not going to side effect myself when you call me.  So, let's go ahead and add some Spec# goodness to the equation. 

    [Pure]
    public Point2D Add(Size2D other)
    {
        double newX = x + other.Height;
        double newY = y + other.Width;
           
        return new Point2D(newX, newY);
    }

    But, now Spec# will warn us that our other might be null, and that could be bad....  So, let's fix that to add some real constraints for the preconditions.

    [Pure]
    public Point2D Add(Size2D other)
        requires other != null
    {
        double newX = x + other.Height;
        double newY = y + other.Width;
           
        return new Point2D(newX, newY);
    }

    Of course I could have put some ensures as well to ensure the result will be the addition, but you get the point.

    Turning To Design by Contract

    Now of course we have to be a pragmatist about things.  At no point did I say that we can't have side effects ever.  That would be Haskell and they put themselves into a nasty corner with that and the only way around it was with monads, that can be a bit clumsy.  Instead, I want to refocus where we do them and be more aware of what you're modifying.

    In our previous examples, we cut down on the number of places where we had our side effects.  But, this does not eliminate them, instead gather them in the appropriate places.  Now when we deal with entities, they are very much mutable, and so we need to be aware when and how side effects get introduced.  To really get to the heart of the matter, we need to verify the preconditions, the postconditions and mostly our invariants.  In a traditional application written in C#, we could throw all sorts of assertions into our code to make sure that we are in fact conforming to our contract.  Or we can write our unit tests to ensure that they conform to them.  This is an important point in Eric Evans' book when talking about assertions in the Supple Design chapter.

    Once again, Spec# enters again as a possible savior to our issue.  This allows us in our code, to model our preconditions and our postconditions as part of our method signature.  Invariants as well can be modeled as well into our code as well.  These ideas came from Eiffel but are very powerful when used for good.

    Let's make a quick example to show how invariants and preconditions and postconditions work.  Let's create an inventory class, and keep in mind it's just a sample and not anything I'd ever use, but it proves a point.  So let's lay out the inventory class and we'll set some constraints.  First, we'll have the number of items remaining.  That number of course can never go below zero.  Therefore, we need an invariant that enforces that.  Also, when we remove items from the inventory, we need to make sure that we're not going to dip below zero.  Very important things to keep in mind.

    public class Inventory
    {
        private int itemsRemaining;
        private int reorderPoint;
       
        invariant itemsRemaining >= 0;
       
        public Inventory()
        {
            itemsRemaining = 200;
            reorderPoint = 50;
            base();
        }
       
        public void RemoveItems(int items)
            requires items <= ItemsRemaining;
            ensures ItemsRemaining == old(ItemsRemaining) - items;
        {
            expose(this)
            {
                itemsRemaining -= items;
            }

            // Check reorder point
        }
       
        public int ItemsRemaining { get { return itemsRemaining; } }

        // More stuff here in class
    }

    What I was able to express is that I set up my invariants in the constructor.  You cannot continue in a Spec# program unless you set the member variable that's included in the invariant.  Also, look at the RemoveItems method.  We set one precondition that states that number of items requested must be less than or equal to the number left.  And we set the postcondition which states that the items remaining must be the difference between the old items remaining and the items requested.  Pretty simple, yet powerful.  We had to expose our invariant while modifying it so that it could be verified, however.  But, doesn't it feel good to get rid of unit tests that prove what I already did in my method signature?

    Wrapping Things Up

    So, I hope after reading this, you've thought more about your design, and where you are modifying state and that you have intention revealing interfaces to tell the coder what exactly you are going to do.  The Design by Contract features of Spec# also play a role in this to state in no uncertain terms what exactly the method can do with the preconditions and postconditions and through my class with my invariants.  Of course you can use your regular C#, or language of choice to model the same kind of things, yet not as intention revealing.

    So, where to go from here?  Well, if you've found Spec# interesting, let Microsoft know about it.  Join the campaign that Greg and I are harping on and say, "I Want Spec#!"

    kick it on DotNetKicks.com

  • Thinking Inside the Box and Premature Optimization

    At the last DC ALT.NET meeting, there was a good discussion regarding premature optimization.  Anything that involves this brings me to a rather famous quote by a great computer scientist, Donald Knuth which states:

    "We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil."

    Don't Think Five Steps Ahead
     
    The context of the conversation revolved around how when you learn a new language, you have a tendency to think inside the box and try not to prematurely optimize the code, instead, just meet the original intent of what you were trying to do as quickly and efficiently as possible and make it conform to the specification.  For example, one person there was a .NET guy who knew nothing of Java until put on a project recently where it was exclusively used.  This forced him to think more clearly about the problem and not just throw design patterns, caching solutions and so on.  When we are familiar with a language and all of its nuances, it sometimes gets the better of us, and we start throwing frameworks in there that have done things for us in the past just because they seemed appropriate then. It rang very true for me as well when I did my first Ruby on Rails application and I saw that I didn't need to bring in X framework or Y framework and my solution did just fine without it.  In fact, I thought it was a stronger piece because I didn't clutter it with frameworks and instead solved the direct domain problem at hand first.

    It kind of reminds me of a conversation I once had with a developer which went like this:

    Me: Why did you use x for this piece?
    Him:  Because it's always worked for me in the past.
    Me:  What problem does it solve?  Did you have that problem this time around?
    Him:  Well, no, I was just thinking five steps ahead

    So, basically what we can infer from this conversation is that the pain point just hadn't been hit yet.  Instead, reflexively, we have a tendency to throw these things in there because at one point, for one particular project, we felt that pain.  That's not to say that optimization is a bad thing, but once we start doing it, we need concrete measures for what the optimization is trying to fix and how well it does it.  Another part to consider is how easy is it to read.

    ADD with DDD

    Some of the guidance for this can be traced back to Domain Driven Design.  With this, you pay more attention to the model, the ubiquitous language and so on, and the frameworks in turn will come into play.  Instead, many people put their frameworks first and try to get the domain model to fit around it.  They are distracted by shiny things with their ADD to put the domain model first and then the frameworks.  I know I've been guilty of it in the past and it's been a learning adventure when I was earlier in my career.

    I'll be back next with a real technology post on IoC, Unity and all that, so stay tuned.  Until next time...

    kick it on DotNetKicks.com