Flutter’da Tasarım Desenleri: Fabrika Yöntemi (Flutter Design Patterns: Factory Method)

IT for your business

Flutter Design Patterns: Factory Method

Fabrika yöntemi (Factory Method) tasarım deseni, nesne oluşturma işlemlerinin merkezi bir noktadan kontrol edilmesini sağlar ve böylece nesne oluşturma işlemleri daha esnek hale getirilir. Bu tasarım deseni, bir sınıfın alt sınıflarının nesne oluşturma işlemini gerçekleştirmesine izin verir. Bu sayede ana sınıf, nesne oluşturma sürecine dahil olmadan alt sınıfların nesne oluşturma işlemini yönetebilir.

Fabrika yöntemi (Factory Method) tasarım deseni, Flutter’da kullanılabilen birçok diğer programlama dillerinde olduğu gibi sıklıkla kullanılır. Bu desen, özellikle uygulamanın ilerleyen zamanlarında yeni özelliklerin eklendiği zamanlarda kullanışlıdır. Fabrika yöntemi tasarım deseni, uygulamada bir değişiklik yapılması gerektiğinde, değişikliğin sadece fabrika sınıfında yapılması gerektiği anlamına gelir.

Flutter’da fabrika yöntemi (Factory Method) tasarım deseni kullanıldığında, nesne oluşturma işlemini gerçekleştirmek için bir arayüz veya soyut sınıf kullanılır. Bu sınıf, nesne oluşturma sürecinde kullanılacak yöntemleri tanımlar. Daha sonra, fabrika sınıfı bu arayüzü veya soyut sınıfı uygular ve nesne oluşturma işlemlerini gerçekleştirir. Bu sayede, uygulamanın farklı bölümlerinde farklı alt sınıflar kullanılarak nesneler oluşturulabilir.

Fabrika yöntemi (Factory Method) tasarım deseni, Flutter uygulamalarında özellikle widget oluşturma işlemlerinde sıklıkla kullanılır. Bu desen, uygulamanın widget oluşturma işlemlerini kolaylaştırarak ve daha esnek hale getirerek, uygulamanın performansını ve bakımını artırır.

Analiz (Analysis)

Factory Method tasarım deseninin genel yapısı şu şekildedir:

factory method 55e3bc32d517530c18eb093f2cff65fd
Flutter'da Tasarım Desenleri: Fabrika Yöntemi (Flutter Design Patterns: Factory Method) 4

Factory Method Tasarım Deseni Yapısı

Creator – fabrika metodunu bildirir, bu metod yeni ürün nesneleri döndürür. Fabrika metodu soyut olarak tanımlanabilir, böylece tüm alt sınıfların bunu uygulaması zorlanabilir. Bu sınıf, varsayılan ConcreteProduct nesnesi döndüren bir fabrika yöntemi için varsayılan bir uygulama da sağlayabilir. ConcreteCreator – fabrika metodunu geçersiz kılarak ConcreteProduct’un bir örneğini döndürür. Fabrika metodu her zaman yeni bir nesne örneği oluşturmak zorunda değildir. Örneğin, nesne örneği önbellekte saklanabilir ve fabrika metodunu çağırdığınızda daha sonra döndürülebilir. Product – fabrika metodunun oluşturduğu tüm nesneler için ortak bir arayüz tanımlar. ConcreteProduct – Product arayüzünü uygular; bu nesnenin örneği, belirli ConcreteCreator sınıfı tarafından döndürülür.

Uygulanabilirlik (Applicability)

Factory Method tasarım deseni, bir uygulama şu özelliklere sahip olduğunda kullanılabilir:

  • Sınıfların oluşturulmasını alt sınıflara devretmek istendiği durumlarda.
  • Yeni nesnelerin oluşturulmasının özellikle alt sınıflar tarafından belirlenmesi gerektiği durumlarda.
  • Bir uygulamanın farklı tipteki nesneleri dinamik olarak yaratabilmesi gerektiği durumlarda.
  • Bir uygulamanın alt sınıfların birbirlerine bağımlılığını azaltarak esneklik ve sürdürülebilirlik kazanması gerektiği durumlarda.

Flutter uygulamalarında, Factory Method tasarım deseni, widget oluşturma ve diğer nesne oluşturma görevleri için kullanılabilir. Widget oluşturulması sırasında Factory Method tasarım deseni kullanılarak, uygulama belirli gereksinimlere bağlı olarak farklı türde widget’lar oluşturabilir ve widget oluşturma işlemi düzenli ve sürdürülebilir hale getirilebilir.

Uygulama (Implementation)

Flutter kullanırken aynı kod tabanını kullanıyor olsanız da, genellikle farklı platformlarda farklı görünümlere sahip olmaları gerektiği talebi olur. Flutter bağlamında hayal edilebilecek en basit kullanım durumu, Android veya iOS cihaz kullanmanıza göre Materyal veya Cupertino stili widget’lar göstermektir.

UI’da uygun widget’ı göstermek için mevcut platformu kontrol etmeli ve Material veya Cupertino widget’ı sağlamalısınız (bu durumda basit bir if ifadesi çalışacaktır). Genel olarak, bu tür bir uygulama esnek değildir:

  • Farklı platformlar için farklı widget’ların gerektiği her yerde mevcut platform kontrol edilmelidir;
  • Yeni bir platform tanıtıldığında (örneğin, Web), kodu sürdürmek zor olacaktır – ek kontroller tanıtılmalı ve if ifadeleri genişletilecektir.

Fabrika yöntemi tasarım deseni, bu soruna nispeten basit bir çözüm sunar: Her platforma özgü widget, ortak soyut yaratıcı sınıfı genişleten kendi somut yaratıcı alt sınıfına sahiptir. Bu, UI kodunun tüm özel bileşenlerin ortak arayüzüne (temel sınıf) bakması gerektiği anlamına gelir ve mevcut platforma göre uygun bir fabrika yöntemi çağrılır ve widget oluşturulur – artık kod bu bileşenlerin belirli uygulamalarına atıfta bulunmak zorunda değildir.

Bu yaklaşımın bir örneği olarak, mevcut platformu seçebileceğiniz bir sayfa oluşturacağız (radyo düğmeleri kullanarak simüle edilir) ve buna bağlı olarak uygun bir uyarı iletişim kutusu (Material veya Cupertino widget’ı) gösterilecektir.

Sınıf diyagramı (Class diagram)

Aşağıdaki sınıf diyagramı, Factory Method tasarım kalıbının uygulanmasını göstermektedir:

factory method implementation f7a1cd7b1af96550ed26852367b0d803
Flutter'da Tasarım Desenleri: Fabrika Yöntemi (Flutter Design Patterns: Factory Method) 5

Sınıf Diyagramı – Factory Method tasarım kalıbının uygulanması

CustomDialog, tüm özel uyarı kutuları için bir temel sınıf olarak kullanılan soyut bir sınıftır:

getTitle() – UI’de kullanılan uyarı kutusu başlığını döndüren soyut bir yöntemdir; create() – uyarı kutusunun özel uygulamasını (UI bileşeni / widget’ı) döndüren soyut bir yöntemdir; show() – create() yöntemini çağırarak uyarı kutusunu oluşturur ve UI’da gösterir.

AndroidAlertDialog ve IosAlertDialog, CustomDialog sınıfını genişleten ve soyut yöntemlerini uygulayan somut sınıflardır. AndroidAlertDialog, AlertDialog türünden Material stili bir uyarı kutusu oluştururken IosAlertDialog, CupertinoAlertDialog türünden Cupertino stili bir uyarı kutusu oluşturur.

Widget, CupertinoAlertDialog ve AlertDialog, Flutter kütüphanesinin zaten uygulanmış sınıfları (widget’ları) dır.

FactoryMethodExample, özel uyarı kutusu türünün show () yöntemini kullanarak gösterilmesi için CustomDialog sınıfını içerir.

CustomDialog

Özel iletişim kutularını göstermek için kullanılan soyut bir sınıftır. CustomDialog sınıfı, iletişim kutusunu göstermek için temel mantığı uygular (show () yöntemi). İletişim kutusunun kendisi için yalnızca create () yönteminin başlığı sağlanır ve CustomDialog’ı genişleten her özel sınıf, belirli bir uyarı iletişim kutusunun özel bir Widget nesnesini döndürerek bunu uygulamalıdır.

abstract class CustomDialog {
  String getTitle();
  Widget create(BuildContext context);

  Future<void> show(BuildContext context) async {
    final dialog = create(context);

    return showDialog<void>(
      context: context,
      barrierDismissible: false,
      builder: (_) {
        return dialog;
      },
    );
  }
}

Alert dialogs

AndroidAlertDialog – CustomDialog’u genişleten ve create () yöntemini Material AlertDialog widget kullanarak uygulayan somut bir uyarı iletişim kutusu sınıfıdır.

class AndroidAlertDialog extends CustomDialog {
  @override
  String getTitle() {
    return 'Android Alert Dialog';
  }

  @override
  Widget create(BuildContext context) {
    return AlertDialog(
      title: Text(getTitle()),
      content: const Text('This is the material-style alert dialog!'),
      actions: <Widget>[
        TextButton(
          onPressed: () {
            Navigator.of(context).pop();
          },
          child: const Text('Close'),
        ),
      ],
    );
  }
}

IosAlertDialog – CustomDialog’u genişleten ve create () yöntemini Cupertino (iOS) CupertinoAlertDialog widget kullanarak uygulayan somut bir uyarı iletişim kutusu sınıfıdır.

class IosAlertDialog extends CustomDialog {
  @override
  String getTitle() {
    return 'iOS Alert Dialog';
  }

  @override
  Widget create(BuildContext context) {
    return CupertinoAlertDialog(
      title: Text(getTitle()),
      content: const Text('This is the cupertino-style alert dialog!'),
      actions: <Widget>[
        CupertinoButton(
          onPressed: () {
            Navigator.of(context).pop();
          },
          child: const Text('Close'),
        ),
      ],
    );
  }
}

Örnek

FactoryMethodExample, CustomDialog nesnelerinin bir listesini içerir. Belirli bir iletişim kutusunu listeden seçtikten sonra showCustomDialog() yöntemini tetikleyerek, seçilen iletişim kutusu show() yöntemi çağrılarak gösterilir.

class FactoryMethodExample extends StatefulWidget {
  const FactoryMethodExample();

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

class _FactoryMethodExampleState extends State<FactoryMethodExample> {
  final List<CustomDialog> customDialogList = [
    AndroidAlertDialog(),
    IosAlertDialog(),
  ];

  int _selectedDialogIndex = 0;

  Future _showCustomDialog(BuildContext context) async {
    final selectedDialog = customDialogList[_selectedDialogIndex];

    await selectedDialog.show(context);
  }

  void _setSelectedDialogIndex(int? index) {
    setState(() {
      _selectedDialogIndex = index!;
    });
  }

  @override
  Widget build(BuildContext context) {
    return ScrollConfiguration(
      behavior: const ScrollBehavior(),
      child: SingleChildScrollView(
        padding: const EdgeInsets.symmetric(
          horizontal: LayoutConstants.paddingL,
        ),
        child: Column(
          children: <Widget>[
            DialogSelection(
              customDialogList: customDialogList,
              selectedIndex: _selectedDialogIndex,
              onChanged: _setSelectedDialogIndex,
            ),
            const SizedBox(height: LayoutConstants.spaceL),
            PlatformButton(
              materialColor: Colors.black,
              materialTextColor: Colors.white,
              onPressed: () => _showCustomDialog(context),
              text: 'Show Dialog',
            ),
          ],
        ),
      ),
    );
  }
}

Gördüğünüz gibi, showCustomDialog() yönteminde belirli bir uyarı iletişim kutusu uygulamasının uygulanmasına bağlı olunmadığı sürece CustomDialog sınıfını genişletir ve show() yöntemini sağlar. Ayrıca, iletişim kutusu bileşeninin uygulanması ayrı bir fabrika yönteminde (CustomDialog sınıfının özel uygulaması içindeki create() yöntemi) kapsüllenmiştir ve tanımlanmıştır. Bu nedenle, UI mantığı, uygulamanın UI uygulamasını etkilemeden bağımsız olarak değiştirilebilen herhangi bir özel uyarı iletişim kutusu sınıfına sıkı sıkıya bağlı değildir.

Bir yanıt yazın