mardi 5 mai 2015

builder pattern - methods with preconditions

For testing purposes, I have a Factory that produces Products using a Builder. Each Product can have a status (Available/ InUse/ Disposed/ etc). I need to produce products in various states.

My problem is that, in order for me to produce a Product with, let's say, Disposed status, it first needs to be InUse ( must create it using new ProductBuilder().CheckIn().Dispose().Build(); not just new ProductBuilder().Dispose().Build();)

How can I (or must I ?) enforce this precondition for a builder method and keep the cyclomatic complexity of 1 (so it doesn't need further testing).

I don't wish to use something like if (product.Status == Product.INUSE) {...} and throwing exceptions for each possible scenario (different states need different preconditions).

Since the builder is private, do I need to enforce this? do I just rely on the programmer to know the order in which the methods need to be called and just add some comments before each builder method? do I choose a different pattern (which?).

public static class ProductFactory
{
    private class ProductBuilder
    {
        private Product product;

        public ProductBuilder()
        {
            product = new Product {Status = product.AVAILABLE};
        }

        public ProductBuilder Dispose()
        {
            product.Status = product.DISPOSED; return this;
        }

        public ProductBuilder CheckIn()
        {
            product.Status = product.INUSE; return this;
        }

        public Product Build()
        {
            return product;
        }
    }

    public static Product CreateAvailable()
    {
        return new ProductBuilder().Build();
    }

    public static Product CreateInUse()
    {
        return new ProductBuilder().CheckIn().Build();
    }

    public static Product CreateDisposed()
    {
        return new ProductBuilder().CheckIn().Dispose().Build();
    }
}

Aucun commentaire:

Enregistrer un commentaire