Builder Vs. Constructor Vs. Factory

Thomas Darimont

Erfahrenes Mitglied
Hallo,

zur Objekt-Konstruktion gibt es mehrere Wege. Der gängiste ist einen Konstruktor zu bemühen um an eine Instanz einer Klasse zu kommen. Daneben gibts noch die Möglichkeit eine (statische) Factory zu erzeugen welche die Objekt-Erzeugung über spezielle Factory Methoden übernimmt. In der Regel haben Konstrutkoraufrufe und Aufrufe von Factory Methoden das Problem das sie bei steigender Parameteranzahl schnell unübersichtlich werden. Mit dem Builder-Pattern kann dem Abhilfe geschafft werden :) (Man hat hier natürlich immer noch die Möglichkeit entsprechende Parameter Objekte zu erstellen die die Parameter für den Konstrutor oder die Factory Methode kapseln. Ein Trick ist nun genau den Builder als solches ParameterObjekt zu verwenden ;-))

C#:
using System;
using System.Collections.Generic;
using System.Text;

namespace De.Tutorials.Training
{
    public class BuilderExample
    {

        public static void Main(string[] args)
        {
            Cake ordinarilyConstructedCake = new Cake(12, 100, 12, 100, 5, 2);

            Console.WriteLine(ordinarilyConstructedCake);

            Cake nicelyConstructedCake = new Cake.Builder(100, 12, 12).WithApples(5).WithBananas(2).WithSalt(100).Build();

            Console.WriteLine(nicelyConstructedCake);
        }
    }

    public class Cake
    {

        public class Builder
        {

            internal int sugar;
            internal int milk;
            internal int eggs;

            public int Salt
            {
                get { return salt; }
            } internal int salt;

            public Builder WithSalt(int value)
            {
                this.salt = value;
                return this;
            }

            public int Apples
            {
                get { return apples; }
            } internal int apples;

            public Builder WithApples(int value)
            {
                this.apples = value;
                return this;
            }


            public int Bananas
            {
                get { return bananas; }
            } internal int bananas;

            public Builder WithBananas(int value)
            {
                this.bananas = value;
                return this;
            }


            public Builder(int milk, int sugar, int eggs)
            {
                this.milk = milk;
                this.sugar = sugar;
                this.eggs = eggs;
            }

            public Cake Build()
            {
                return new Cake(this);
            }
        }


        public int Sugar
        {
            get { return sugar; }
            set { sugar = value; }
        } private int sugar;

        public int Milk
        {
            get { return milk; }
            set { milk = value; }
        } private int milk;

        public int Salt
        {
            get { return salt; }
            set { salt = value; }
        } private int salt;

        public int Eggs
        {
            get { return eggs; }
            set { eggs = value; }
        } private int eggs;

        public int Apples
        {
            get { return apples; }
            set { apples = value; }
        } private int apples;

        public int Bananas
        {
            get { return bananas; }
            set { bananas = value; }
        } private int bananas;


        public Cake(int sugar, int milk, int eggs, int salt, int apples, int bananas)
        {
            this.sugar = sugar;
            this.milk = milk;
            this.eggs = eggs;
            this.salt = salt;
            this.apples = apples;
            this.bananas = bananas;
        }

        public Cake(Builder builder)
        {
            this.sugar = builder.sugar;
            this.milk = builder.milk;
            this.eggs = builder.eggs;
            this.salt = builder.salt;
            this.apples = builder.apples;
            this.bananas = builder.bananas;
        }

        public override string ToString()
        {
            return String.Format("Cake[sugar:{0},milk:{1},eggs:{2},salt:{3},apples:{4},bananas:{5}]",sugar,milk,eggs,salt,apples,bananas);
        }

    }
}

Ausgabe:
Code:
Cake[sugar:12,milk:100,eggs:12,salt:100,apples:5,bananas:2]
Cake[sugar:12,milk:100,eggs:12,salt:100,apples:5,bananas:2]
Drücken Sie eine beliebige Taste . . .


Gruß Tom
 
Hallo,

Hier mal noch ne Variante die etwas weniger redundanter Datenhaltung ausschaut ;-)
C#:
using System;
using System.Collections.Generic;
using System.Text;

namespace De.Tutorials.Training
{
    public class BuilderExample
    {

        public static void Main(string[] args)
        {
            Cake ordinarilyConstructedCake = new Cake(12, 100, 12, 100, 5, 2);

            Console.WriteLine(ordinarilyConstructedCake);

            Cake nicelyConstructedCake = new Cake.Builder(100, 12, 12).WithApples(5).WithBananas(2).WithSalt(100).Build();

            Console.WriteLine(nicelyConstructedCake);
        }
    }

    public class Cake
    {

        public class Builder
        {

            Cake prototype;

            public int Salt
            {
                get { return this.prototype.Salt; }
            }

            public Builder WithSalt(int value)
            {
                this.prototype.Salt = value;
                return this;
            }

            public int Apples
            {
                get { return this.prototype.Apples; }
            }

            public Builder WithApples(int value)
            {
                this.prototype.Apples = value;
                return this;
            }


            public int Bananas
            {
                get { return this.prototype.Bananas; }
            }

            public Builder WithBananas(int value)
            {
                this.prototype.Bananas = value;
                return this;
            }


            public Builder(int milk, int sugar, int eggs)
            {
                this.prototype = new Cake(milk, sugar, eggs);
            }

            public Cake Build()
            {
                Cake result = this.prototype;
                this.prototype = new Cake();
                return result;
            }
        }


        public int Sugar
        {
            get { return sugar; }
            set { sugar = value; }
        } private int sugar;

        public int Milk
        {
            get { return milk; }
            set { milk = value; }
        } private int milk;

        public int Salt
        {
            get { return salt; }
            set { salt = value; }
        } private int salt;

        public int Eggs
        {
            get { return eggs; }
            set { eggs = value; }
        } private int eggs;

        public int Apples
        {
            get { return apples; }
            set { apples = value; }
        } private int apples;

        public int Bananas
        {
            get { return bananas; }
            set { bananas = value; }
        } private int bananas;

        public Cake()
        {

        }

        public Cake(int milk, int sugar, int eggs){
            this.sugar = sugar;
            this.milk = milk;
            this.eggs = eggs;
        }

        //nur zur demonstration des "normalen" Constructors...
        public Cake(int sugar, int milk, int eggs, int salt, int apples, int bananas) : this(milk,sugar,eggs)
        {
            this.salt = salt;
            this.apples = apples;
            this.bananas = bananas;
        }

        public override string ToString()
        {
            return String.Format("Cake[sugar:{0},milk:{1},eggs:{2},salt:{3},apples:{4},bananas:{5}]",sugar,milk,eggs,salt,apples,bananas);
        }

    }
}

Gruß Tom
 
Zurück