Flutter Tasarım Desenleri: Builder (Flutter Design Patterns: Builder)

IT for your business

Flutter Design Patterns: Builder

Builder, Flutter’da sık kullanılan bir tasarım desenidir. Builder tasarım deseni, özellikle büyük ve karmaşık nesnelerin yapısını oluşturmak için kullanılır. Bu desen, nesne yapısını ayrıştırmak ve daha sonra farklı parçaları ayrı ayrı oluşturmak için kullanılır.

Builder deseni, nesne yapısının ayrıntılarını gizlemeye yardımcı olur ve yapılandırma işlemini daha kolay ve esnek hale getirir. Bu desen, özellikle nesne yapısının farklı varyasyonlarını oluşturmak istediğinizde veya nesne yapısında değişiklik yapmak istediğinizde faydalıdır.

Flutter’da Builder tasarım desenini uygulamak için, bir Builder sınıfı oluşturmanız gerekir. Bu sınıf, nesne yapısını oluşturmak için gerekli metodları içerir. Daha sonra, oluşturulacak nesne yapısının farklı parçalarını oluşturmak için ayrı sınıflar oluşturabilirsiniz. Bu sınıfların her biri, Builder sınıfındaki metodları kullanarak nesne yapısının farklı parçalarını oluşturur.

Builder tasarım deseni, özellikle büyük ve karmaşık nesnelerin yapısını oluştururken, nesne yapısının esnekliğini korumak ve değişiklik yapmayı kolaylaştırmak için faydalıdır.

Builder tasarım deseni nedir?

Builder tasarım deseni, nesne yönelimli programlama (OOP) alanında kullanılan bir tasarım desenidir. Bu desen, karmaşık nesnelerin yapısını oluşturmak için kullanılır. Nesne yapısını ayrıştırmak ve daha sonra farklı parçaları ayrı ayrı oluşturmak için kullanılır. Builder tasarım deseni, nesne yapısının ayrıntılarını gizler ve yapılandırma işlemini daha kolay ve esnek hale getirir.

Builder deseni, özellikle nesne yapısının farklı varyasyonlarını oluşturmak istediğinizde veya nesne yapısında değişiklik yapmak istediğinizde faydalıdır. Bu desen, nesne yapısının birçok parçasını içeren ve değişken sayıda adımdan oluşan bir yapının oluşturulması sırasında kullanılır.

Builder tasarım deseni, bir Builder arayüzü, ConcreteBuilder sınıfları ve bir Director sınıfı içerir. Builder arayüzü, nesne yapısının parçalarını oluşturmak için gereken yöntemleri tanımlar. ConcreteBuilder sınıfları, Builder arayüzündeki yöntemleri uygular ve nesne yapısının farklı parçalarını oluşturur. Director sınıfı, ConcreteBuilder sınıflarını kullanarak nesne yapısını oluşturur.

Builder tasarım deseni, kod tekrarını en aza indirir ve daha az karmaşık ve daha esnek bir nesne yapısı oluşturmanıza yardımcı olur. Ayrıca, nesne yapısının oluşturulması sırasında kullanılan ayrıntıları gizler, böylece nesne yapısının daha iyi bir şekilde korunmasına yardımcı olur.

Analiz (Analysis)

Builder Tasarım Deseni, karmaşık bir nesnenin oluşturulmasını, temsilinden ayırarak, aynı oluşturma sürecinin farklı temsillerini oluşturabilmesine izin veren bir yaratıcı tasarım desenidir. Flutter’da, karmaşık widget veya görünümleri oluşturmak için çok kullanışlı bir desendir.

Builder Tasarım Deseni’nin ana fikri, karmaşık bir nesnenin yapısını temsilden ayırmak ve aynı oluşturma sürecinin farklı temsillerini oluşturabilmesine izin vermektir. Bu ayrım, nesneyi oluşturma sorumluluğuna sahip olan bir yapılandırıcı sınıfı ve oluşturma sürecini koordine eden bir yönetici sınıfı kullanarak gerçekleştirilir. Yapılandırıcı sınıf, nesnenin çeşitli parçalarını oluşturmakla sorumludur, yönetici sınıfı ise yapılandırıcı sınıfı çağırmak ve oluşturma sürecini koordine etmekle sorumludur.

Flutter’da, bu desen, birden çok parçanın oluşturulması gereken karmaşık widget veya görünümleriniz olduğunda faydalı olabilir. Örneğin, farklı yapılandırmalara sahip birçok farklı widget içeren bir görünüme sahipseniz, Builder Tasarım Deseni, karmaşıklığı yönetmenize ve görünümü oluşturmayı kolaylaştırmanıza yardımcı olabilir.

Flutter’da Builder Tasarım Deseni kullanmak, kodunuzu daha bakımı kolay ve daha kolay değiştirilebilir hale getirebilir. Oluşturma sürecini temsilden ayırarak, nesnenin temsiline etki etmeden oluşturma sürecini değiştirebilirsiniz. Bu, özellik eklemeyi veya kaldırmayı, nesnenin yapılandırmasını değiştirmeyi veya yapılandırıcı sınıfın farklı bir uygulamasına geçmeyi kolaylaştırır.

Sonuç olarak, Builder Tasarım Deseni, Flutter’da karmaşık widget veya görünümleri oluştururken karmaşıklığı yönetmek için güçlü bir araçtır. Nesnenin temsilinden yapılandırmasını ayırmak, kodunuzu değiştirmeyi ve bakımını yapmayı daha kolay hale getirir.

Uygulanabilirlik (Applicability)

Builder Tasarım Deseni, birden çok parçadan veya yapılandırmadan oluşan karmaşık nesneler oluşturmanız gereken durumlarda en uygun olan tasarım desenidir. Flutter’da, bu desen, farklı yapılandırmalara sahip birçok küçük widget’ın oluşturulması gereken karmaşık widget veya görünümleriniz varsa faydalı olabilir.

Eğer bir widget oluşturuyorsanız ve birçok yapılandırma seçeneği içeriyorsa veya birden çok küçük widget’ın oluşturulması gerekiyorsa, Builder Tasarım Deseni karmaşıklığı yönetmenize ve kodunuzu daha kolay bakılabilir hale getirmenize yardımcı olabilir.

Ayrıca Builder Tasarım Deseni, aynı nesnenin farklı temsillerini oluşturmanız gerektiği durumlarda da faydalıdır. Örneğin, bir çizelgeyi çizgi veya bar olarak göstermeniz gerekiyorsa, Builder Tasarım Deseni, oluşturma sürecini aynı tutarken farklı temsiller oluşturmanıza yardımcı olabilir.

Builder Tasarım Deseni aynı zamanda, nesnenin temsilinden bağımsız olarak oluşturma sürecini değiştirmeniz gerektiğinde de faydalıdır. Bu, yapılandırma sürecinin nesnenin temsilini etkilemeden değiştirilebilmesi nedeniyledir.

Özetle, Builder Tasarım Deseni, farklı yapılandırmalar veya temsiller gerektiren karmaşık nesneler oluşturmanız gereken durumlarda uygulanabilir. Flutter’da, birden çok küçük widget’ın oluşturulması gereken karmaşık widget veya görünümler için faydalıdır. Nesnenin temsilini etkilemeden oluşturma sürecini değiştirmeniz gerektiğinde de faydalıdır.

Uygulama (Implementation)

Flutter’da Builder Tasarım Deseni’ni uygulamak için şu adımları izlemeniz gerekiyor:

  1. Karmaşık nesne oluşturmak için arayüzü tanımlayan soyut bir Builder sınıfı oluşturun. Bu sınıf, nesnenin farklı yapılandırmalarını veya parçalarını ayarlamak için yöntemlere sahip olmalıdır.
  2. Builder arayüzünü uygulayan somut bir Concrete Builder sınıfı oluşturun ve nesnenin farklı yapılandırmalarını veya parçalarını oluşturmak için özelleştirilmiş uygulamalar sağlayın.
  3. Builder arayüzünü kullanarak nesneyi oluşturan bir Director sınıfı oluşturun. Bu sınıf, oluşturma sürecini yönetmek ve Builder nesnesindeki uygun yöntemleri çağırmakla sorumlu olmalıdır.
  4. Uygun yöntemleri çağırarak karmaşık nesneyi oluşturun.

Flutter’da Builder Tasarım Deseni’nin örnek bir uygulaması şöyle olabilir:

// Adım 1: Soyut Builder sınıfını oluşturun
abstract class WidgetBuilder {
  void buildButton();
  void buildTextField();
  void buildLabel();
  Widget getResult();
}

// Adım 2: Somut Builder sınıfını oluşturun
class ComplexWidgetBuilder implements WidgetBuilder {
  Button _button;
  TextField _textField;
  Label _label;

  @override
  void buildButton() {
    _button = Button();
    _button.color = Colors.blue;
  }

  @override
  void buildTextField() {
    _textField = TextField();
    _textField.color = Colors.white;
  }

  @override
  void buildLabel() {
    _label = Label();
    _label.text = "Complex Widget";
  }

  @override
  Widget getResult() {
    return Container(
      child: Column(
        children: [
          _button,
          _textField,
          _label,
        ],
      ),
    );
  }
}

// Adım 3: Director sınıfını oluşturun
class WidgetDirector {
  WidgetBuilder _builder;

  void setBuilder(WidgetBuilder builder) {
    _builder = builder;
  }

  Widget buildWidget() {
    _builder.buildButton();
    _builder.buildTextField();
    _builder.buildLabel();
    return _builder.getResult();
  }
}

// Adım 4: Karmaşık nesneyi oluşturun
WidgetDirector director = WidgetDirector();
director.setBuilder(ComplexWidgetBuilder());
Widget complexWidget = director.buildWidget();

Bu örnekte, karmaşık bir widget oluşturmak için arayüzü tanımlayan soyut WidgetBuilder sınıfı oluşturduk. Ayrıca, WidgetBuilder arayüzünü uygulayan ComplexWidgetBuilder adlı somut bir Builder sınıfı oluşturduk ve düğme, metin alanı ve etiket oluşturmak için özelleştirilmiş uygulamalar sağladık. Son olarak, WidgetBuilder arayüzünü kullanarak karmaşık widget’ı oluştur

Sınıf Diyagramı (Class diagram)

Flutter’da Builder tasarım kalıbının sınıf diyagramı aşağıdaki gibidir:

  +------------------+          +----------------+
  |  WidgetBuilder   |          |      Widget    |
  +------------------+          +----------------+
  |  buildButton()   |          |                |
  |  buildTextField()|          |                |
  |  buildLabel()    |          |                |
  |  getResult()     |<-------- |                |
  +------------------+          +----------------+
            ^                           ^
            |                           |
            |                           |
  +------------------+          +----------------+
  |ComplexWidgetBuilder|          |     Button     |
  +------------------+          +----------------+
  |  buildButton()   |<-------- |     color      |
  |  buildTextField()|          |                |
  |  buildLabel()    |          |                |
  |  getResult()     |          +----------------+
  +------------------+
            ^
            |
            |
  +------------------+
  |   TextField      |
  +------------------+
  |    color         |
  +------------------+
            ^
            |
            |
  +------------------+
  |      Label       |
  +------------------+
  |      text        |
  +------------------+

Sınıf diyagramı aşağıdaki bileşenleri gösterir:

  • WidgetBuilder: Karmaşık bir nesne oluşturmak için arayüzü tanımlayan soyut sınıf. Bir düğme, metin kutusu, etiket oluşturmak ve sonucu almak için yöntemler içerir.
  • ComplexWidgetBuilder: Karmaşık bir bileşen oluşturmak için WidgetBuilder arabirimini uygulayan somut bir sınıf. Bir düğme, metin kutusu ve etiket oluşturmak için yöntemler içerir ve son bileşeni getResult() yöntemi aracılığıyla döndürür.
  • Widget: Builder deseninde oluşturulacak son karmaşık nesne.
  • Button: Rengi olan basit bir widget sınıfı.
  • TextField: Rengi olan basit bir widget sınıfı.
  • Label: Metni olan basit bir widget sınıfı.

Yönetici sınıfı, karmaşık nesneyi oluşturma işlemini yöneten bir yardımcı sınıf olduğu için bu sınıf diyagramında temsil edilmemiştir.

Bileşen (Ingredient)

Flutter’da Builder tasarım kalıbının ana bileşenleri şunlardır:

  • WidgetBuilder soyut sınıfı: Bir düğme, metin kutusu veya etiket gibi karmaşık bir nesne oluşturmak için bir arayüz tanımlar. Her bileşeni oluşturmak ve sonucu almak için yöntemler içerir.
  • ComplexWidgetBuilder somut sınıfı: WidgetBuilder arabirimini uygulayarak bir form veya diyalog kutusu gibi karmaşık bir nesne oluşturur. Her bileşeni oluşturmak için yöntemler içerir ve son bileşeni getResult() yöntemi aracılığıyla döndürür.
  • Widget sınıfı: Builder kalıbının oluşturduğu karmaşık nihai nesneyi temsil eder. Bu bir form, diyalog kutusu veya herhangi bir karmaşık widget olabilir.
  • Basit widget sınıfları: Basit işlevsellik sağlayan Button, TextField ve Label gibi basit widget sınıfları, karmaşık widget’ları oluşturmak için kullanılır.

Builder kalıbı, karmaşık bir nesnenin oluşturulmasını temsilinden ayırmak ve aynı nesnenin farklı temsillerini oluşturma yöntemi sunar. Bu, Flutter uygulamalarında karmaşık widget’ların yapılandırılmış ve yeniden kullanılabilir bir şekilde oluşturulmasını kolaylaştırır ve uygulamanın bakımını ve genişletilebilirliğini artırabilir.

Verilen açıklamaya göre, burada bir Ingredient soyut sınıfının örnek bir uygulaması bulunmaktadır:

abstract class Ingredient {
  final String name;
  final List<String> allergens;

  Ingredient(this.name, this.allergens);
}

Bu Ingredient soyut sınıfı iki alan içerir: name ve allergens. name alanı malzemenin adını saklar ve allergens alanı, malzemeye ilişkili alerjenlerin bir listesini saklar. Ingredient sınıfı, doğrudan örneklendirilmemesi için abstract olarak işaretlenmiştir.

Özel malzemeleri temsil eden diğer sınıflar, örneğin Flour veya Egg, bu Ingredient sınıfını genişletir ve kendi uygulamalarını yapılandırıcı ve herhangi ek metod veya alanları sağlar. Örneğin:

class Flour extends Ingredient {
  final bool isWholeGrain;

  Flour(String name, List<String> allergens, this.isWholeGrain)
      : super(name, allergens);
}

Bu örnekte, Flour sınıfı Ingredient sınıfını genişletir ve isWholeGrain alanını ekler, unun tam buğday olup olmadığını belirtmek için. Flour sınıfı, super anahtar kelimesini kullanarak Ingredient sınıfının yapılandırıcısını çağıran kendi yapılandırıcısını sağlar. Flour sınıfı, un malzemelerinin özel özelliklerini temsil etmek için gerekli olan ek yöntem veya alanları da ekleyebilir.

Concrete ingredients

Tüm bu sınıflar, Ingredient sınıfını genişleterek belirli bir malzemeyi temsil ederler ve name (ad) değerini ve allergens (alerjenler) listesini belirlerler.

Big Mac ekmeği:

class BigMacBun extends Ingredient {
  BigMacBun() {
    name = 'Big Mac Ekmeği';
    allergens = ['Buğday'];
  }
}

Normal ekmeği:

class RegularBun extends Ingredient {
  RegularBun() {
    name = 'Normal Ekmeği';
    allergens = ['Buğday'];
  }
}

Peynir:

class Cheese extends Ingredient {
  Cheese() {
    name = 'Peynir';
    allergens = ['Süt', 'Soya'];
  }
}

Grill baharatı:

class BeefPatty extends Ingredient {
  BeefPatty() {
    name = 'Grill baharatı';
    allergens = [];
  }
}
  • Sığır köftesi:
class BeefPatty extends Ingredient {
  BeefPatty() {
    name = 'Sığır köftesi';
    allergens = [];
  }
}
  • McChicken köftesi:
class McChickenPatty extends Ingredient {
  McChickenPatty() {
    name = 'McChicken köftesi';
    allergens = [
      'Buğday',
      'Buttermilk Crispy Chicken\'da kullanılan aynı fritözde pişirildiği için içinde süt alerjeni bulunur'
    ];
  }
}
  • Big Mac sosu:
class BigMacSauce extends Ingredient {
  BigMacSauce() {
    name = 'Big Mac sosu';
    allergens = ['Yumurta', 'Soya', 'Buğday'];
  }
}
  • Ketçap:
class Ketchup extends Ingredient {
  Ketchup() {
    name = 'Ketçap';
    allergens = [];
  }
}
  • Mayonez:
class Mayonnaise extends Ingredient {
  Mayonnaise() {
    name = 'Mayonez';
    allergens = ['Yumurta'];
  }
}
  • Hardal:
class Mustard extends Ingredient {
  Mustard() {
    name = 'Hardal';
    allergens = [];
  }
}
  • Soğan:
class Onions extends Ingredient {
  Onions() {
    name = 'Soğan';
    allergens = [];
  }
}
  • Turşu dilimleri:
class PickleSlices extends Ingredient {
  PickleSlices() {
    name = 'Turşu dilimleri';
    allergens = [];
  }
}
  • Doğranmış marul:
class ShreddedLettuce extends Ingredient {
  ShreddedLettuce() {
    name = 'Doğranmış marul';
    allergens = [];
  }
}

Burger

Burger sınıfı, burger hakkındaki bilgileri saklamak için kullanılan basit bir sınıftır: fiyatı ve içerdiği malzemelerin bir listesi. Ayrıca, getFormattedIngredients(), getFormattedAllergens() ve getFormattedPrice() gibi sınıf yöntemleri, bu değerleri insanlar tarafından okunaklı bir formatta döndürür.

class Burger {
  final List<Ingredient> _ingredients = [];
  late double _price;

  void addIngredient(Ingredient ingredient) {
    _ingredients.add(ingredient);
  }

  String getFormattedIngredients() {
    return _ingredients.map((x) => x.getName()).join(', ');
  }

  String getFormattedAllergens() {
    final allergens = <String>{};

    for (final ingredient in _ingredients) {
      allergens.addAll(ingredient.getAllergens());
    }

    return allergens.join(', ');
  }

  String getFormattedPrice() {
    return '\$${_price.toStringAsFixed(2)}';
  }

  // ignore: use_setters_to_change_properties
  void setPrice(double price) {
    _price = price;
  }
}

BurgerBuilderBase

BurgerBuilderBase, burger ve fiyat özelliklerini depolayan soyut bir sınıftır. Burger nesnesini oluşturmak ve döndürmek için varsayılan yöntemler tanımlar ve fiyatını ayarlamak için yöntemler sağlar. Ayrıca, türetilen burger oluşturucu sınıfları tarafından uygulanması gereken birkaç soyut yöntem tanımlar.

abstract class BurgerBuilderBase {
  @protected
  late Burger burger;
  @protected
  late double price;

  void createBurger() {
    burger = Burger();
  }

  Burger getBurger() {
    return burger;
  }

  void setBurgerPrice() {
    burger.setPrice(price);
  }

  void addBuns();
  void addCheese();
  void addPatties();
  void addSauces();
  void addSeasoning();
  void addVegetables();
}

Concrete builder sınıfı BigMacBuilder, bir Big Mac yaratmak için şu malzemeleri kullanır: BigMacBun, Cheese, BeefPatty, BigMacSauce, GrillSeasoning, Onions, PickleSlices ve ShreddedLettuce.

class BigMacBuilder extends BurgerBuilderBase {
  BigMacBuilder() {
    price = 3.99;
  }

  @override
  void addBuns() {
    burger.addIngredient(BigMacBun());
  }

  @override
  void addCheese() {
    burger.addIngredient(Cheese());
  }

  @override
  void addPatties() {
    burger.addIngredient(BeefPatty());
  }

  @override
  void addSauces() {
    burger.addIngredient(BigMacSauce());
  }

  @override
  void addSeasoning() {
    burger.addIngredient(GrillSeasoning());
  }

  @override
  void addVegetables() {
    burger.addIngredient(Onions());
    burger.addIngredient(PickleSlices());
    burger.addIngredient(ShreddedLettuce());
  }
}

CheeseburgerBuilder – Builer sınıfından türetilen bir sınıftır. Aşağıdaki malzemeleri kullanarak bir Cheeseburger oluşturur:

  • RegularBun
  • Cheese
  • BeefPatty
  • Ketchup
  • Mustard
  • GrillSeasoning
  • Onions
  • PickleSlices

CheeseburgerBuilder sınıfı BurgerBuilder sınıfındaki soyut yöntemleri uygular ve burger özelliği için Cheeseburger sınıfının bir örneğini oluşturur.

class CheeseburgerBuilder extends BurgerBuilderBase {
  CheeseburgerBuilder() {
    price = 1.09;
  }

  @override
  void addBuns() {
    burger.addIngredient(RegularBun());
  }

  @override
  void addCheese() {
    burger.addIngredient(Cheese());
  }

  @override
  void addPatties() {
    burger.addIngredient(BeefPatty());
  }

  @override
  void addSauces() {
    burger.addIngredient(Ketchup());
    burger.addIngredient(Mustard());
  }

  @override
  void addSeasoning() {
    burger.addIngredient(GrillSeasoning());
  }

  @override
  void addVegetables() {
    burger.addIngredient(Onions());
    burger.addIngredient(PickleSlices());
  }
}

Sorunuzda bir yazım hatası var gibi görünüyor. Bağlama göre, üçüncü cümlede “bir hamburger oluşturur” yerine “bir peynirsiz hamburger oluşturur” demek istediğinizi varsayıyorum. İşte düzeltilmiş versiyonu:

HamburgerBuilder – şu malzemeleri kullanarak bir hamburger oluşturur: RegularBun, BeefPatty, Ketchup, Mustard, GrillSeasoning, Onions ve PickleSlices. addCheese() yöntemi bu yapılandırıcı için uygun değildir, bu yüzden uygulama sağlanmaz (atlanır).

class HamburgerBuilder extends BurgerBuilderBase {
  HamburgerBuilder() {
    price = 1.0;
  }

  @override
  void addBuns() {
    burger.addIngredient(RegularBun());
  }

  @override
  void addCheese() {
    // Not needed
  }

  @override
  void addPatties() {
    burger.addIngredient(BeefPatty());
  }

  @override
  void addSauces() {
    burger.addIngredient(Ketchup());
    burger.addIngredient(Mustard());
  }

  @override
  void addSeasoning() {
    burger.addIngredient(GrillSeasoning());
  }

  @override
  void addVegetables() {
    burger.addIngredient(Onions());
    burger.addIngredient(PickleSlices());
  }
}

McChickenBuilder – RegularBun, McChickenPatty, Mayonez ve ShreddedMarul gibi malzemeleri kullanarak bir McChicken yapar. addCheese() ve addSeasoning() yöntemleri bu oluşturucu için geçerli değildir, bu nedenle uygulama sağlanmaz (atlanır).

class McChickenBuilder extends BurgerBuilderBase {
  McChickenBuilder() {
    price = 1.29;
  }

  @override
  void addBuns() {
    burger.addIngredient(RegularBun());
  }

  @override
  void addCheese() {
    // Not needed
  }

  @override
  void addPatties() {
    burger.addIngredient(McChickenPatty());
  }

  @override
  void addSauces() {
    burger.addIngredient(Mayonnaise());
  }

  @override
  void addSeasoning() {
    // Not needed
  }

  @override
  void addVegetables() {
    burger.addIngredient(ShreddedLettuce());
  }
}

BurgerMaker

Burger yapım sürecini yöneten ve yapılan sonucu döndüren bir yönetici sınıfıdır. Builder’ın belirli bir uygulaması yapıcı fonksiyonu yoluyla sınıfa enjekte edilir.

class BurgerMaker {
  BurgerBuilderBase burgerBuilder;

  BurgerMaker(this.burgerBuilder);

  // ignore: use_setters_to_change_properties
  void changeBurgerBuilder(BurgerBuilderBase burgerBuilder) {
    this.burgerBuilder = burgerBuilder;
  }

  Burger getBurger() {
    return burgerBuilder.getBurger();
  }

  void prepareBurger() {
    burgerBuilder.createBurger();
    burgerBuilder.setBurgerPrice();

    burgerBuilder.addBuns();
    burgerBuilder.addCheese();
    burgerBuilder.addPatties();
    burgerBuilder.addSauces();
    burgerBuilder.addSeasoning();
    burgerBuilder.addVegetables();
  }
}

Örnek

BuilderExample, BurgerMaker sınıfı nesnesini başlatır ve içerir. Ayrıca, UI’yi kullanarak belirli bir oluşturucuyu seçmek için kullanılan BurgerMenuItem nesnelerinin/listesinin bir listesini içerir.

class BuilderExample extends StatefulWidget {
  const BuilderExample();

  @override
  _BuilderExampleState createState() => _BuilderExampleState();
}

class _BuilderExampleState extends State<BuilderExample> {
  final BurgerMaker _burgerMaker = BurgerMaker(HamburgerBuilder());
  final List<BurgerMenuItem> _burgerMenuItems = [];

  late BurgerMenuItem _selectedBurgerMenuItem;
  late Burger _selectedBurger;

  @override
  void initState() {
    super.initState();

    _burgerMenuItems.addAll([
      BurgerMenuItem(
        label: 'Hamburger',
        burgerBuilder: HamburgerBuilder(),
      ),
      BurgerMenuItem(
        label: 'Cheeseburger',
        burgerBuilder: CheeseburgerBuilder(),
      ),
      BurgerMenuItem(
        label: 'Big Mac\u00AE',
        burgerBuilder: BigMacBuilder(),
      ),
      BurgerMenuItem(
        label: 'McChicken\u00AE',
        burgerBuilder: McChickenBuilder(),
      )
    ]);

    _selectedBurgerMenuItem = _burgerMenuItems[0];
    _selectedBurger = _prepareSelectedBurger();
  }

  Burger _prepareSelectedBurger() {
    _burgerMaker.prepareBurger();

    return _burgerMaker.getBurger();
  }

  void _onBurgerMenuItemChanged(BurgerMenuItem? selectedItem) {
    setState(() {
      _selectedBurgerMenuItem = selectedItem!;
      _burgerMaker.changeBurgerBuilder(selectedItem.burgerBuilder);
      _selectedBurger = _prepareSelectedBurger();
    });
  }

  @override
  Widget build(BuildContext context) {
    return ScrollConfiguration(
      behavior: const ScrollBehavior(),
      child: SingleChildScrollView(
        padding: const EdgeInsets.symmetric(
          horizontal: LayoutConstants.paddingL,
        ),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Row(
              children: <Widget>[
                Text(
                  'Select menu item:',
                  style: Theme.of(context).textTheme.headline6,
                ),
              ],
            ),
            DropdownButton(
              value: _selectedBurgerMenuItem,
              items: _burgerMenuItems
                  .map<DropdownMenuItem<BurgerMenuItem>>(
                    (BurgerMenuItem item) => DropdownMenuItem(
                      value: item,
                      child: Text(item.label),
                    ),
                  )
                  .toList(),
              onChanged: _onBurgerMenuItemChanged,
            ),
            const SizedBox(height: LayoutConstants.spaceL),
            Row(
              children: <Widget>[
                Text(
                  'Information:',
                  style: Theme.of(context).textTheme.headline6,
                ),
              ],
            ),
            const SizedBox(height: LayoutConstants.spaceM),
            BurgerInformationColumn(burger: _selectedBurger),
          ],
        ),
      ),
    );
  }
}

Yönetici sınıfı BurgerMaker, oluşturucunun belirli bir uygulamasıyla ilgilenmez – belirli bir uygulama çalışma zamanında değiştirilebilir ve farklı bir sonuç sağlayabilir. Ayrıca, bu tür bir uygulama, BurgerBuilderBase sınıfını genişleten yeni bir oluşturucu eklemeyi, mevcut kodu bozmadan başka bir farklı ürün temsili sağlamak için kolayca yapmayı mümkün kılar.

Bir yanıt yazın