Mastering Flutter: Building Scalable and Maintainable Apps with Modular Architecture [tr]

Salih Can
4 min readJul 1, 2023

--

Herkese Selamlar,

Modüler yapıya sahip mobil uygulamalar, geliştirme sürecinde esneklik, sürdürülebilirlik ve yeniden kullanılabilirlik gibi birçok avantaj sunar. Bu avantajlar, büyük ölçekli uygulamaların geliştirilmesi sırasında özellikle önemlidir. Flutter, bu alanda güçlü bir çözüm sunan popüler bir çerçevedir.

Bu makalede, Flutter kullanarak nasıl multi modular bir uygulama geliştirebileceğimizi keşfedeceğiz. Multi modular yapı, uygulamayı bağımsız parçalara ayırarak her bir parçanın kendi sorumluluklarını ve işlevlerini yerine getirmesini sağlar. Her bir modül, belirli bir özelliği veya işlevi temsil eder ve bağımsız olarak geliştirilebilir, test edilebilir ve dağıtılabilir.

Mimari Yaklaşım

Modern bir mobil uygulama geliştirmek için doğru mimari yaklaşımı seçmek, uygulamanın sürdürülebilirliği, ölçeklenebilirliği ve bakım kolaylığı açısından önemlidir. Bu bağlamda modüler bir yapı kullanmak büyük bir avantaj sağlar. Bu bölümde, Flutter’da kullanılan modüler yaklaşımın avantajlarını, katmanlı bir yapıyı ve bu katmanlar arasındaki ilişkileri ele alacağız. Ayrıca modüllerin ve bağımlılıkların nasıl yönetildiğini ve uygulamanın genel yapısal özelliklerini açıklayacağız.

Modüler Yapının Avantajları

Modüler bir yapı, bir Flutter uygulamasının bölünmüş ve bağımsız parçalara ayrılmasını sağlar. Her bir modül, kendi sorumluluk alanına odaklanır ve genel uygulama yapısını karmaşıklıktan kurtarır. Bu yaklaşımın avantajları şunları içerir:

  • Daha Yüksek Sürdürülebilirlik: Modüler yapı, uygulamanın farklı bölümlerinin izole edilmesini sağlar. Her bir modülün kendi sorumlulukları ve sınırları vardır, bu da kod tabanının daha sürdürülebilir ve bakımı daha kolay hale gelmesini sağlar.
  • Ölçeklenebilirlik: Modüler yapının kullanılması, uygulamanın daha fazla özellik eklenmesi veya var olan özelliklerin genişletilmesi durumunda daha kolay ölçeklenebilmesini sağlar. Yeni modüller eklemek veya mevcut modülleri güncellemek, uygulamanın genel yapısını etkilemeden gerçekleştirilebilir.
  • Bağımlılıkların Yönetimi: Modüler yapı, bağımlılıkların yönetimini kolaylaştırır. Modüller arasındaki bağımlılıklar açık bir şekilde tanımlanır ve bu sayede bağımlılık çatışmaları ve karmaşıklıklar önlenir.
  • Paralel Geliştirme: Modüler yapı, ekip içinde paralel olarak çalışmayı kolaylaştırır. Her bir modül, farklı bir ekip üyesi tarafından geliştirilebilir ve bir modülde yapılan değişiklikler, diğer modülleri etkilemez.

Uygulama Katmanları ve İlişkileri

Recipe Finder — Moduler Architecture

Modüler bir Flutter uygulaması genellikle dört ana katmanı içerir: Domain, Data, Presentation ve Çekirdek.

Yukarıdaki görselde, bu makale serisinin sonunda tamamlanan ‘Recipe Finder’ uygulamasının modülerleştirilmiş halini görebilirsiniz.

  • İş Mantığı Katmanı: Bu katman, uygulama için temel iş mantığını ve iş süreçlerini içerir. Veri modelleri, hizmetler, işlemler ve diğer domain odaklı sınıflar bu katmanda yer alır. Domain katmanı, uygulamanın çekirdek işlevselliğini temsil eder ve diğer katmanlara bağımlı olmaz.
  • Veri Katmanı: Veri katmanı, uygulama verilerinin işlenmesi ve yönetilmesinden sorumludur. Veri kaynaklarına (API’lar, veritabanları vb.) erişim sağlar, veri dönüşümlerini yapar ve gerekirse veri saklama işlemlerini gerçekleştirir. Bu katman, domain katmanının veriye erişimini soyutlar.
  • Sunum Katmanı: Sunum katmanı, kullanıcı arayüzünün oluşturulduğu ve kullanıcıyla etkileşimlerin gerçekleştirildiği katmandır. Widget’ları, ekranlarınızı, formları ve kullanıcı arayüzüne odaklı diğer bileşenleri içerir. Bu katman, kullanıcı arayüzünün görüntülenmesi ve kullanıcı eylemlerinin işlenmesi için diğer katmanlarla etkileşim halindedir.
  • Çekirdek Katmanı: Çekirdek katmanı, projenin hiçbir katmanına bağımlı olmaz ve aksine diğer katmanların bu katmandan adeta beslendiği katmandır. Bu katmanda, base yapılar, genel eklentiler gibi projeye genel katkıda bulunabilecek özellikler bulunur.

Bu katmanlar arasındaki ilişki, tek yönlü bir akışla sağlanır. Presentation katmanı, domain katmanına bağımlıdır ve iş mantığını kullanır. Data katmanı ise domain katmanından verileri alır ve veri kaynaklarına erişim sağlar.

Modüllerin ve Bağımlılıkların Yönetimi

Modüler bir Flutter uygulaması, her bir modülün bağımsız olarak geliştirilmesini ve yönetilmesini sağlar. Modüller, genellikle işlevsellik veya özellikler bazında ayrılır. Her bir modül, kendi içinde domain, data ve presentation katmanlarını içerebilir.

Modüller arasındaki bağımlılıklar, bağımlılık enjeksiyonu (dependency injection) kullanılarak yönetilir. Bağımlılık enjeksiyonu, bağımlılıkların modüller arasında geçirilmesini ve her bir modülün bağımlılıkları kullanmasını sağlar. Bu sayede modüller arasında sıkı bağımlılıklar azaltılır ve değişikliklerin bir modülün diğerlerini etkilemesi önlenir.

Modüllerin ve bağımlılıkların yönetimi için genellikle bir bağımlılık enjeksiyon paketi kullanılır. Flutter için popüler bağımlılık enjeksiyonu çözümleri arasında “get_it”, “injectable”, “kiwi” gibi paketler bulunur. Bu paketler, bağımlılık enjeksiyonunu kolaylaştırır ve modüller arasındaki bağımlılıkları sağlamlaştırır.

Uygulamanın genel yapısal özellikleri, modüler yapının tasarımına ve kullanılan bağımlılık enjeksiyon çözümüne bağlıdır. Modüler bir yapı, uygulamanın ölçeklenebilirliğini, sürdürülebilirliğini ve bakım kolaylığını artırır.

Ornek Uygulama: Recipe Finder

Modüler uygulamadan bahsettiğimize göre, şimdi örnek bir uygulama oluşturarak anlattıklarımızı pekiştirelim. Örnek uygulamanın kaynak kodlarını makalenin sonunda bulabilirsiniz.

Recipe Finder adlı örnek proje için yukarıda gördüğünüz gibi dosya yapılandırmasını oluşturdum. Genel olarak, presentation, domain, data ve core katmanlarını açıkladım. Bu katmanları ‘modules’ adını verdiğim bir klasör altında ‘flutter package’ örnekleriyle oluşturdum.

Modüler mimaride karşılaşacağınız iki sorun vardır. Bunlardan biri modül versiyonları ve 3. bağımlılık yönetimi, diğeri ise bağımlılık enjeksiyonudur.

  • İlk sorunu ‘melos’ adlı bir paketle çözdüm. Melos ile her bir modül için farklı komutlar çalıştırabilir veya tüm alt modüllerde flutter pub get komutunu tek bir komutla çalıştırabilirsiniz.
  • Ikinci sorun olan bağımlılık enjeksiyonu problemini ‘get_it’ paketini kullanarak ele aldım. Uzun süredir Android geliştirici olarak geliştirmeler yaptığım için bağımlılık yönetimini annotation olarak adlandırdığımız etiketler ile gerçekleştirmiştim. Bunu Flutter’da da devam ettirmek adına ‘get_it’ paketini ‘injectable’ paketinin güçlendirmesiyle kullanmaya karar verdim. Bu iki güzel paketle birlikte bağımlılık enjeksiyonu gibi çok güçlü bir problemi de çözmüş oldum.

Bu çözümler sonucunda projenin temel iskeleti aşağıdaki gibi oldu.

Bu yazıyla birlikte genel olarak ‘modüler mimari nasıl olmalı?’ sorusuna bir giriş yapmış ve yaptığım örnek projenin temel iskeletini tanıtmış oldum. Dependency injection nasıl yapılır? Bu paketleri nasıl kullanılır? gibi soruların cevaplarını ilgili paketin dokümantasyon sayfasından bulabilirsiniz. İki paket de oldukça detaylı bir dokümantasyona sahip.

Oluşturduğum örnek projeyi aşağıdaki bağlantıdan inceleyebilirsiniz.

Herhangi bir sorunuz olduğunda buradan veya LinkedIn gibi kanallardan iletişime geçebilirsiniz. Görüşmek üzere 👋

--

--

Salih Can
Salih Can

No responses yet