samedi 29 août 2020

What is the difference between the builder design pattern and using classes that inherit from other?

Recently I'm studying design patterns and I've been seeing a pattern called builder that in theory is supposed to encapsulate the complexity of a class, and this is the example I've been practicing:

class ExampleBuilder
{
    static void Main(string[] args)
    {
        Kitchen kit = new Kitchen();

        // One pizza 
        kit.NextPizza(new FourCheeseBuilder("Family"));
        kit.PreparePizza();
        var FourCheesePizza = kit.PizzaComplete;

        // Another pizza
        kit.NextPizza(new HawaiianBuilder("Small"));
        kit.PreparePizza();
        var HawaiianPizza = kit.PizzaComplete;
    }
}

// Final Product
public class Pizza
{
    public string Dough { get; set; }
    public string Sauce { get; set; }
    public string Stuff { get; set; }
    public string Size { get; set; }
    public bool BeenFolded { get; set; }

    public Pizza()
    {

    }

    public Pizza(string Size, string Dough, string Sauce, string Stuff, bool BeenFolded) : this()
    {
        this.Size = Size;
        this.Dough = Dough;
        this.Sauce = Sauce;
        this.Stuff = Stuff;
        this.BeenFolded = BeenFolded;
    }
}

// Builder
public abstract class PizzaBuilder
{
    // Protected para que las clases que implementen puedan acceder
    protected Pizza _pizza;
    public string Size { get; set; }

    public Pizza ObtainPizza() { return _pizza; }



    // Un paso para cada una de las propiedades
    public virtual void PasoPrepararDough()
    {

    }

    public virtual void PasoAñadirSauce()
    {

    }

    public virtual void PasoPrepararStuff()
    {

    }

    public virtual void PasoDoblarPoizza()
    {

    }

}

// BuilderConcrete
public class HawaiianBuilder : PizzaBuilder
{
    public HawaiianBuilder(string size)
    {
        _pizza = new Pizza
        {
            Size = size
        };
    }
    public override void PasoPrepararDough()
    {
        _pizza.Dough = "Soft";
    }

    public override void PasoAñadirSauce()
    {
        _pizza.Sauce = "Sweet";
    }

    public override void PasoPrepararStuff()
    {
        _pizza.Stuff = "pineapple, tomato, ham";
    }
}

// Another BuilderConcrete
public class FourCheeseBuilder : PizzaBuilder
{
    public FourCheeseBuilder(string size)
    {
        _pizza = new Pizza
        {
            Size = size
        };
    }
    public override void PasoPrepararDough()
    {
        _pizza.Dough = "Coocked";
    }

    public override void PasoAñadirSauce()
    {
        _pizza.Sauce = "Roquefort";
    }

    public override void PasoPrepararStuff()
    {
        _pizza.Stuff = "mozzarela, gorgonzola, parmesano, ricotta";
    }
}

// Director
public class Kitchen
{
    private PizzaBuilder _pizzaBuilder;

    public void NextPizza(PizzaBuilder pizzaBuilder)
    {
        _pizzaBuilder = pizzaBuilder;
    }

    public void PreparePizza()
    {
        _pizzaBuilder.PasoPrepararDough();
        _pizzaBuilder.PasoAñadirSauce();
        _pizzaBuilder.PasoPrepararStuff();
    }

    public Pizza PizzaComplete
    {
        get { return _pizzaBuilder.ObtainPizza(); }

    }
}

I had to do all that staff to define two types of different classes, and I don't understand why is these better than do this:

 class ExampleBuilder
{
    static void Main(string[] args)
    {

        //One Pizza
        var FourCheesePizza2 = new FourCheese2("Family");

        //Another Pizza
        var HawaiianPizza2 = new HawaiianPizza2("Small");
    }
}

// Final product
public abstract class Pizza2
{
    public string Dough { get; set; }
    public string Sauce { get; set; }
    public string Stuff { get; set; }
    public string Size { get; set; }
    public bool BeenFolded { get; set; }

    public Pizza2()
    {

    }

    public Pizza2(string Size, string Dough, string Sauce, string Stuff, bool BeenFolded) : this()
    {
        this.Size = Size;
        this.Dough = Dough;
        this.Sauce = Sauce;
        this.Stuff = Stuff;
        this.BeenFolded = BeenFolded;
    }
}

public class HawaiianPizza2 : Pizza2
{
    public HawaiianPizza2(string size)
    {
        Size = size;
        Dough = "Soft";
        Sauce = "Sweet";
        Stuff = "pineapple, tomato, ham";
        BeenFolded = false;
    }
}

public class FourCheese2 : Pizza2
{
    public FourCheese2(string size)
    {
        Size = size;
        Dough = "Coocked";
        Sauce = "Roquefort";
        Stuff = "mozzarela, gorgonzola, parmesano, ricotta";
        BeenFolded = true;
    }
}

I get the same result but occupying much less lines of code, and that's why I don't know what the pattern builder is really for.

Aucun commentaire:

Enregistrer un commentaire