Pages

Showing posts with label OOP. Show all posts
Showing posts with label OOP. Show all posts

Monday, December 16, 2013

The Builder pattern

The builder pattern is an object construction pattern that is usually used to handle complex objects creation/initialization. A very good sign that it could be applied is when you start creating lots of constructors, or when your single constructors has lots of parameters, that is because you need the object to be constructed and returned in a state that you can actually use it.


The builder pattern also relies on constructing the object step-by-step, by method calls. Consider making a pizza for example. You first pour the tomato sauce on the dough, then you add cheese, pepperoni and olive oil. Then you bake it. Can you see the steps? If we were to create a pizza with a single constructor, we'd have something like this:

public Pizza(Dough dough, TomatoSauce sauce, Cheese cheese, Pepperoni pepperoni, OliveOil oil)

What if we'd actually want different toppings on the pizza? For example, instead of pepperoni, I'd like to have some sausage on top of the cheese, and I'm not a fan of olive oil. We'd then create another constructor overload for my pizza, right?

public Pizza(Dough dough, TomatoSauce sauce, Cheese cheese, Sausage sausage)

But now I want pepperoni, sausage AND some mushrooms! I think you can already see where this is going: we'd have a different constructor for each set of toppings we'd like on our pizza.

The pizza example is a classic one. With the builder pattern, using a builder object, I can make a pizza with as many toppings as I want! I can also chose whether I want olive oil on it or not.

We then have our pizza, which now has a list of toppings, instead of individual properties for each one of them:

public class Pizza
{
    public Pizza()
    {
        Toppings = new List<Topping>();            
    }

    public Dough Dough { get; set; }
    public TomatoSauce TomatoSauce { get; set; }
    public List<Topping> Toppings { get; set; }
    public bool HasOliveOil { get; set; }
}


Now we can easily implement our builder in a way that it'll be able to make whatever pizza we want:


public class PizzaBuilder
{
    private Pizza Pizza { get; set; }

    public PizzaBuilder()
    {
        Pizza = new Pizza();
    }

    public PizzaBuilder WithThinDough()
    {
        Pizza.Dough = new Dough { Type = DoughType.Thin };

        return this;
    }

    public PizzaBuilder WithThickDough()
    {
        Pizza.Dough = new Dough { Type = DoughType.Thick };

        return this;
    }

    public PizzaBuilder WithFlavoredTomatoSauce()
    {
        Pizza.TomatoSauce = new TomatoSauce { Type = TomatoSauceType.Flavored }; 

        return this;
    }

    public PizzaBuilder WithTomatoOnlyTomatoSauce()
    {
        Pizza.TomatoSauce = new TomatoSauce { Type = TomatoSauceType.TomatoOnly };

        return this;
    }

    public PizzaBuilder WithOliveOil()
    {
        Pizza.HasOliveOil = true;

        return this;
    }

    public PizzaBuilder WithTopping(Topping topping)
    {
        Pizza.Toppings.Add(topping);

        return this;
    }

    public Pizza Bake()
    {
        return Pizza;
    }
}


Notice that I left the whole responsibility of creating the tomato sauce and dough to the builder, as oppose to how I implemented how the toppings are added. I also created a property for the two first instead of creating sub-types for them. There's no real reason for this, they are just implementation details.


Just imagine now that for each one of the toppings we'd have a subclass. So we'd for example have a class called Sausage which extends the Topping class.

class Sausage : Topping
{
    // [...]
}

To get the toppings, I'll just create a class called Toppings which has a set of properties representing each one of the toppings. We could even apply the factory pattern in it.

After having all of these classes, we could then use the builder like this:

var pizzaBuilder = new PizzaBuilder();

var pizza = pizzaBuilder.WithThickDough()
                        .WithFlavoredTomatoSauce()
                        .WithTopping(Toppings.Mozzarella)
                        .WithTopping(Toppings.Sausage)
                        .WithTopping(Toppings.Onion)
                        .WithTopping(Toppings.Mushroom)
                        .WithOliveOil()
                        .Bake();


It's really easier to make pizza now, huh?

Now to forget about pizza and get back to our world, just imagine yourself building a complex XML document by taking advantage of the builder pattern. I bet it wouldn't be that much of a hard task.

Thursday, September 26, 2013

"But what if I had to test this?"

It's a fact that developing software using test driven development (TDD) techniques assures a higher quality than other conventional techniques.

TDD consists of making the developer start off with a test, and then write code to make the test pass, repeating this process in cycles. This makes us think about the best design for the smallest unit in code: methods.

Since you have to write the code that consumes your method before writing the actual method, you'll always end up with a simplistic, easy-to-use version of it. It's like putting ahead what you expect from your code, and then writing it. This often tends to push you to the best design: smaller, clearer methods with a single responsibility, fewer lines of code.

But forget about TDD for now, I'll blog about that later.


The message I'm trying to pass here is not "use TDD" or "write unit tests", but at least pretend that you're doing so! - By the way, you should totally experiment with TDD and PLEASE, DO WRITE UNIT TESTS!





But what if I had to test this?

Those of you who use TDD or just write unit tests will, eventually, change your design to make the testing easier.

But those of you who don't do any of them, you should.


Whenever writing a big fat method with lots and lots of lines of code, think about it. Ask yourself the question: "How would I test this?".


For example, take the following method:

public boolean DoSomething()
{
    var result = from child in this.Father.Children
                 from grandChild in child.GrandChildren
                 where (child.Foo == "Foo" &&
                       grandChild.Bar == "Bar" &&
                       child.Value > 10 &&
                       child.Value < 50 || 
                       grandChild.Amount * 100 < 0) ||
                       (child.Value > 100 &&
                       grandChild.Amount * 765 < 10000 &&
                       (child.Foo == "Not Foo" ||
                       ((int)grandChild.Amount ^ 2) == 3600))
                 group child by new { child.Foo, child.Value } into g
                 select new
                     {
                         Sum = g.Sum(child => child.Value),
                         FooMax = g.Max(child => child.Foo)
                     };

    var firstGroupedChild = result.First();

    if (firstGroupedChild.FooMax != "ZZZ")
    {               
        var correctedGrandChild = new GrandChild();

        correctedGrandChild.Bar = "Corrected grand child";
        correctedGrandChild.Amount += firstGroupedChild.Sum * 1.10;

        correctedGrandChild.InsertOnDatabase();

        DataAccessObject.DeleteFromDatabase(firstGroupedChild.FooMax);

        return true;
    }

    return false;
}
I couldn't even think of a bad name to that!


Now ask yourself: "How do I test this?".
A: Man, you're gonna have a bad time...

If the developer who wrote that code had the exact same question in mind from the very beginning, I'm pretty sure he would have dropped the idea of doing so much stuff - including a complex Linq query - on a single method just right there. Imagine how many Unit Tests you would have to write just to test the minimum of something like that. That is a terribly poorly written method.

If you don't test at all, it's actually acceptable to have something like this, given that you're not too worried about the quality of your product anyway. But you should! Do care about quality! Even if you don't assure it, at least remember that it exists!

Also, be a good guy and think about the fellow developer who maintains this code. He'll sure have a terrible time trying to find out just why the hell one of the "child" objects was not found on the first query, and not summed up.


Now imagine if we could translate the method above to the following:

var children = Father.GetChildrenThatSatisfySomeCondition();

var groupedResults = Child.GroupBySomeCondition(children);

var childFooMax = groupedResults.Max(child => child.Foo);

if (childFooMax.Foo!= "ZZZ")
{
    var correctedGrandChild = GrandChild.GetNewCorrectedFromChild(childFooMax);
    
    DataAccessObject.PerformChildCorrectionWithGrandChild(childFooMax, correctedGrandChild);

    return true;
}

return false;


Ooooooh! It all makes sense now! Now I can even understand the logic flow of the things I have to test! I could totally write Unit Tests for each one of the extracted methods now, because they all seem to be small, cohesive, and have a single responsibility.

And that would have been the first choice of design if the developer had thought about testing it before, or while he was writing it.


Code quality - and specially the semantics - matter, always.

Wednesday, July 31, 2013

Boolean parameter VS exposing semantics

This can be a subject of quite long discussions with team mates during coffee hours.
Some team mates might think that simply putting a boolean parameter that slightly changes the behavior of a method is not a big deal. They may even make the parameter optional.

But when is that a good thing? When is it good to "just add a boolean parameter and make it optional"? Well, if it changes the method behavior in the smallest way possible, but even then it matters, then I'd say it's never good.

To prove it, consider the following two calls:

object.DoSomeLengthyWork();
object.DoSomeLengthyWork(true);

I don't know about you, but if I'm the one maintaining this code the first thing that would pop into my head when reading the second line would be "What the hell should be true?". The second thing I'd have to do would be lookup the method definition (or read its summary, if the developer who wrote the method cared enough to even create one), which is pretty easy, just position the cursor over it and press F12 right? Right! But what if that method is defined in another project / solution / dll that you do not have opened in your environment, or you don't even have access to?

And that, my friend, is why I strongly advise you to always go for the better semantics! Specially if you're writing public methods.

What I'm saying here doesn't make much sense if you work in a small company with a small codebase and maybe a team of 2 to 3 developers. But imagine working in a team of 20, 30 or 50 developers. Or even with a small codebase, imagine maintaining code that has been in production for 5 years or more, with no documentation whatsoever. Code whose owner or writer is not even working for the company anymore. I'm sure you'd have a blast trying to find out "what the hell should be true" in the example above.

Wouldn't it be easier if you could just have those two example lines written like this instead?

object.DoSomeSynchronousLengthyWork();
object.DoSomeAsynchronousLengthyWork();

"Ooooh, so that's what that true meant!"

And I won't even mention named arguments for cases like this, because they're pretty evil for distributed solutions. Jon Skeet has an awesome way of stating it, which can be found here and of course, in his book C# in Depth, that I quote:


The silent horror of changing names

In the past, parameter names haven’t mattered much if you’ve only been using C#. Other languages may have cared, but in C# the only times that parameter names were important were when you were looking at IntelliSense and when you were looking at the method code itself. Now, the parameter names of a method are effectively part of the API even if you’re only using C#. If you change them at a later date, code can break—anything that was using a named argument to refer to one of your parameters will fail to compile if you decide to change it. This may not be much of an issue if your code is only consumed by itself anyway, but if you’re writing a public API, be aware that changing a parameter name is a big deal. It always has been really, but if everything calling the code was written in C#, we’ve been able to ignore that until now.

Renaming parameters is bad; switching the names around is worse. That way the calling code may still compile, but with a different meaning. A particularly evil form of this is to override a method and switch the parameter names in the overridden version. The compiler will always look at the deepest override it knows about, based on the static type of the expression used as the target of the method call. You don’t want to get into a situation where calling the same method implementation with the same argument list results in different behavior based on the static type of a variable.


And that my friends, is why when it comes to boolean parameters VS method overloading, I always side with method overloading, that is, when the boolean parameter changes the method's behavior in a way that matters.

PS: C# in Depth is a great read, you should definitely read it.