↑↓ seç · Enter aç · Esc kapat

Mutlu Tekin
Mutlu Tekin
← Yazılar

Bölüm 6 — Konu 27: GetX (Tartışmalı Ama Yaygın)

4 dk okuma #flutter
Dizi · 27/61 Flutter Türkçe Tutorial
  1. Bölüm 1 — Konu 1: Flutter Nedir, Mimarisi (Widget → Element → RenderObject, Skia/Impeller)
  2. Bölüm 1 — Konu 2: Ortam Kurulumu (Flutter SDK, Android Studio/VS Code, Emulator/Simulator, DevTools'a İlk Bakış)
  3. Bölüm 1 — Konu 3: İlk Proje Yapısı (`pubspec.yaml`, `lib/`, Klasör Mimarisi, `flutter create` Anatomisi)
  4. Bölüm 1 — Konu 4: Hot Reload / Hot Restart Ne Yapıyor, Neden Önemli
  5. Bölüm 2 — Konu 5: "Her Şey Widget'tır" Felsefesi, Widget Ağacı
  6. Bölüm 2 — Konu 6: StatelessWidget vs StatefulWidget + `setState()` Derinlemesine (Rebuild Mekanizması)
  7. Bölüm 2 — Konu 7: Temel Layout — Container, Row, Column, Stack, Padding, Align, Center
  8. Bölüm 2 — Konu 8: Constraint Sistemi — "Constraints Go Down, Sizes Go Up, Parent Sets Position"
  9. Bölüm 2 — Konu 9: `Expanded`, `Flexible`, `Spacer`, Intrinsic Widget'lar
  10. Bölüm 3 — Konu 10: MaterialApp/CupertinoApp, Scaffold, AppBar
  11. Bölüm 3 — Konu 11: `ListView`, `GridView`, `SingleChildScrollView` (+ Builder Pattern)
  12. Bölüm 3 — Konu 12: Text, TextStyle, Icon, Image, Asset Yönetimi
  13. Bölüm 3 — Konu 13: Custom Widget Yazma Prensipleri (Composition Over Inheritance)
  14. Bölüm 3 — Konu 14: Navigator 1.0 — Push/Pop, Named Routes
  15. Bölüm 4 — Konu 15: Form, TextField/TextFormField, GlobalKey<FormState>, Validasyon
  16. Bölüm 4 — Konu 16: Theme Sistemi (ThemeData, ColorScheme)
  17. Bölüm 4 — Konu 17: Responsive & Adaptive Tasarım (MediaQuery, LayoutBuilder, OrientationBuilder, Breakpoint Stratejileri)
  18. Bölüm 5 — Konu 18: Future/Async-Await Flutter Bağlamında, FutureBuilder
  19. Bölüm 5 — Konu 19: `Stream`, `StreamBuilder`
  20. Bölüm 5 — Konu 20: HTTP İstekleri (`http` / `dio` Paketleri)
  21. Bölüm 5 — Konu 21: JSON Serialization (Manuel → `json_serializable`/`freezed`)
  22. Bölüm 5 — Konu 22: Local Storage — `shared_preferences` → `Hive` → `sqflite`/Drift
  23. Bölüm 6 — Konu 23: InheritedWidget ve InheritedModel — "Neden setState Yetmiyor" Sorusunun Cevabı
  24. Bölüm 6 — Konu 24: Provider Paketi
  25. Bölüm 6 — Konu 25: Riverpod (Modern Yaklaşım, Provider'ın Halefi)
  26. Bölüm 6 — Konu 26: BLoC/Cubit Pattern (`flutter_bloc`)
  27. Bölüm 6 — Konu 27: GetX (Tartışmalı Ama Yaygın)
  28. Bölüm 6 — Konu 28: Karşılaştırma — Hangi Projede Hangisi?
  29. Bölüm 7 — Konu 29: Navigator 2.0 (Router, RouteInformationParser, RouterDelegate)
  30. Bölüm 7 — Konu 30: `go_router` Paketi (Pratik ve Modern Çözüm)
  31. Bölüm 7 — Konu 31: Deep Linking
  32. Bölüm 7 — Konu 32: Repository Pattern, Katmanlı Mimari (Data/Domain/Presentation)
  33. Bölüm 7 — Konu 33: Dependency Injection (`get_it`, `injectable`)
  34. Bölüm 7 — Konu 34: Clean Architecture Uyarlaması, SOLID Prensipleri
  35. Bölüm 8 — Konu 35: Implicit Animasyonlar
  36. Bölüm 8 — Konu 36: Explicit Animasyonlar (`AnimationController`, `Tween`, `Curve`)
  37. Bölüm 8 — Konu 37: Hero Animasyonları
  38. Bölüm 8 — Konu 38: `CustomPainter` / `Canvas`
  39. Bölüm 8 — Konu 39: Rive / Lottie Entegrasyonu
  40. Bölüm 9 — Konu 40: Platform Channels
  41. Bölüm 9 — Konu 41: Permission Yönetimi (`permission_handler`)
  42. Bölüm 9 — Konu 42: Kamera, Konum, Sensörler
  43. Bölüm 9 — Konu 43: Push Notification (Firebase Cloud Messaging)
  44. Bölüm 9 — Konu 44: Android/iOS Build Sistemleri
  45. Bölüm 10 — Konu 45: Test Yazımı (Unit, Widget, Integration, Golden)
  46. Bölüm 10 — Konu 46: CI/CD
  47. Bölüm 10 — Konu 47: Rebuild Optimizasyonu (`const`, `key` Kullanımı)
  48. Bölüm 10 — Konu 48: DevTools Profiling
  49. Bölüm 10 — Konu 49: Lazy Loading, Pagination, Büyük Liste Performansı
  50. Bölüm 11 — Konu 50: Firebase Ekosistemi (Auth, Firestore, Storage, Functions)
  51. Bölüm 11 — Konu 51: Supabase Alternatifi
  52. Bölüm 11 — Konu 52: GraphQL (Opsiyonel)
  53. Bölüm 11 — Konu 53: Store Yayınlama Süreci (İmzalama, Listing, Versiyonlama)
  54. Bölüm 11 — Konu 54: App Size, Obfuscation, Flavor Yönetimi
  55. Bölüm 12 — Konu 55: Flutter Web / Desktop
  56. Bölüm 12 — Konu 56: Custom `RenderObject` Yazımı
  57. Bölüm 12 — Konu 57: Engine Mimarisi Derinlemesine (Impeller vs Skia)
  58. Bölüm 12 — Konu 58: Plugin Geliştirme, pub.dev'e Paket Yayınlama
  59. Bölüm 12 — Konu 59: Monorepo Mimarisi (Melos)
  60. Bölüm 12 — Konu 60: Erişilebilirlik (Accessibility) Derinlemesine
  61. Bölüm 12 — Konu 61: Yerelleştirme (Localization / i18n)
Dizinin sayfası →
İçindekiler 10 başlık
  1. GetX Nedir?
  2. Paketi Ekleme
  3. Temel Kullanım — GetxController
  4. Widget İçinde Kullanım — Obx
  5. context Olmadan Her Şey — GetX'in İddiası
  6. Neden Bazı Geliştiriciler GetX'i Seviyor?
  7. Neden Bazı Geliştiriciler GetX'e Eleştiri Getiriyor?
  8. Dengeli Bir Sonuç
  9. 🎯 Bu Dersten Çıkarılması Gerekenler
  10. 📝 Ödevler

GetX Nedir?

GetX, sadece bir state management çözümü değil — state management + navigasyon + dependency injection'ı tek bir pakette birleştiren, "hepsi bir arada" (all-in-one) bir framework'tür. Bu ders başlığındaki "tartışmalı" ifadesi bilinçli — GetX, Flutter topluluğunda hem çok sevilen hem de eleştirilen bir araçtır. Bu dersi, dengeli bir bakış açısıyla işleyeceğiz.

Paketi Ekleme

bash
flutter pub add get

Temel Kullanım — GetxController

dart
import 'package:get/get.dart';

class SepetController extends GetxController {
  var sepetSayisi = 0.obs; // '.obs' — GetX'e özgü "observable" yapma

  void ekle() {
    sepetSayisi++; // reaktif — otomatik olarak dinleyicileri günceller
  }
}

.obs — bu, GetX'in en dikkat çekici özelliklerinden biri. Dart Bölüm 6'da öğrendiğimiz normal bir değişken (var sepetSayisi = 0), .obs eklendiğinde "reaktif" (observable) bir değişkene dönüşür — arka planda, GetX bu değeri özel bir wrapper class'a (RxInt) sarmalar. sepetSayisi++ yazdığında, bu otomatik olarak dinleyicilere haber verir — Bölüm 6 Konu 24'te öğrendiğimiz notifyListeners()'ı elle çağırmana bile gerek kalmıyor.

Widget İçinde Kullanım — Obx

dart
final controller = Get.put(SepetController());

class SepetIkonu extends StatelessWidget {
  const SepetIkonu({super.key});

  @override
  Widget build(BuildContext context) {
    return Obx(() => Badge(
      label: Text('${controller.sepetSayisi}'),
      child: Icon(Icons.shopping_cart),
    ));
  }
}

Get.put(SepetController()) — bu, Bölüm 6 Konu 23-26'da öğrendiğimiz Provider/ChangeNotifierProvider gibi bir "enjeksiyon" mekanizmasının çok daha basit bir versiyonudur — BuildContext'e hiç ihtiyaç duymadan, controller'ı bir global registry'e (kayıt defterine) ekler.

Obx(() => ...) — Dart Bölüm 5'te öğrendiğimiz anonim fonksiyon parametre alıyor (tıpkı builder pattern'lerinde olduğu gibi). Obx, içindeki widget ağacının hangi .obs değişkenlere bağımlı olduğunu otomatik olarak tespit eder ve sadece onlar değiştiğinde yeniden çizer — sen BlocBuilder<T, S> veya context.watch<T>() gibi açıkça hangi tipi izleyeceğini belirtmene bile gerek yok.

context Olmadan Her Şey — GetX'in İddiası

dart
// Navigasyon - context OLMADAN!
Get.to(DetayEkrani());

// SnackBar - context OLMADAN!
Get.snackbar('Başlık', 'Mesaj');

// Controller'a HERHANGİ bir yerden erişim - context OLMADAN!
Get.find<SepetController>().ekle();

Bu, GetX'in en çok tartışılan özelliğidir — Bölüm 3 Konu 14'te öğrendiğimiz Navigator.push(context, ...)'u hatırlarsan, GetX bunu tamamen context'siz hale getiriyor. Bu, hem bir kolaylık hem de bir eleştiri kaynağıdır — şimdi her iki tarafı da görelim.

Neden Bazı Geliştiriciler GetX'i Seviyor?

  1. Çok az "boilerplate" (tekrarlayan kod) — Bölüm 6 Konu 24-26'da gördüğümüz Provider/Riverpod/BLoC'un BlocBuilder, ConsumerWidget, StateNotifierProvider gibi yapısal gerekliliklerine kıyasla, GetX çok daha az kod ile aynı işi yapar.
  2. Öğrenme eğrisi düşük — .obs ve Obx mantığı, sezgisel ve hızlı öğrenilir.
  3. Hepsi bir arada — navigasyon, state management, dependency injection, hatta yerelleştirme (localization) tek pakette.
  4. context bağımsızlığı — Bölüm 6 Konu 25'te Riverpod'un bu avantajını övmüştük; GetX bunu daha da ileri götürür.

Neden Bazı Geliştiriciler GetX'e Eleştiri Getiriyor?

  1. Flutter'ın "resmi" felsefesinden sapma — Bölüm 1 Konu 1'de öğrendiğimiz Widget/Element/RenderObject mimarisi, BuildContext'i merkezi bir kavram olarak tasarlamıştır (Bölüm 6 Konu 23'te öğrendiğimiz InheritedWidget de context'e dayanır). GetX'in context'i tamamen atlaması, bazı Flutter'a özgü mekanizmalarla (tema, lokalizasyon context'e bağlı çalışan sistemler) sürtüşme yaratabilir.
  2. Global state riski — Get.put()/Get.find(), aslında global, erişilebilir her yerden bir kayıt defteri oluşturur. Bu, Dart Bölüm 6'da öğrendiğimiz encapsulation (kapsülleme) prensibini zayıflatabilir — herhangi bir widget, uygulamanın herhangi bir controller'ına, hiçbir kısıtlama olmadan erişebilir, bu da büyük projelerde kodun akışını takip etmeyi zorlaştırabilir.
  3. "Sihirli" davranış — Obx'in hangi değişkenlere bağımlı olduğunu otomatik tespit etmesi, Bölüm 6 Konu 24'te öğrendiğimiz context.select<T, R>()'in açık (explicit) yaklaşımına kıyasla, bazen beklenmedik rebuild davranışlarına yol açabilir — çünkü ne zaman, neyin tetiklediği her zaman net olmayabilir.
  4. Test edilebilirlik — Get.find() gibi global erişimler, Riverpod'un (Bölüm 6 Konu 25) övdüğümüz "kolay test edilebilirlik" avantajına göre daha zor test edilebilir bir yapı oluşturabilir (bağımlılıkları "mock"lamak/sahtelemek daha karmaşık hale gelir).

Dengeli Bir Sonuç

Bu, kesin bir "doğru" veya "yanlış" cevabı olmayan bir tartışma — Flutter topluluğu bu konuda bölünmüştür. Bazı büyük, başarılı uygulamalar GetX ile yazılmıştır; bazı büyük takımlar ise bilinçli olarak GetX'ten kaçınır, Provider/Riverpod/BLoC'u tercih eder.

Pratik gözlem noktaları:

  • Küçük-orta projeler, hızlı prototipleme: GetX'in hızı ve azlığı avantaj olabilir.
  • Büyük, uzun soluklu, çok geliştiricili projeler: GetX'in "her şeye her yerden erişim" esnekliği, disiplin gerektirebilir — bazı takımlar bunu riskli bulur.
  • Flutter'ın kendi ekosistemiyle (resmi paketler, dokümantasyon) uyum: Provider/Riverpod, Flutter ekibinin kendi önerdiği desenlere (InheritedWidget tabanlı) daha yakındır.

🎯 Bu Dersten Çıkarılması Gerekenler

  • GetX, state management + navigasyon + dependency injection'ı tek pakette birleştiren, "hepsi bir arada" bir framework'tür.
  • .obs, bir değişkeni reaktif (observable) yapar; Obx, hangi değişkenlere bağımlı olduğunu otomatik tespit eden bir widget'tır.
  • Get.put()/Get.find(), BuildContext'e hiç ihtiyaç duymadan, global bir kayıt defteri üzerinden state'e erişim sağlar.
  • GetX, hızı ve azlığı (boilerplate azlığı) nedeniyle sevilirken; global state riski, Flutter'ın context-merkezli felsefesinden sapması ve test edilebilirlik zorlukları nedeniyle eleştirilir.
  • Bu, topluluğun bölündüğü bir konudur — kesin bir doğru cevap yoktur, proje büyüklüğüne ve takım tercihine göre değişir.

📝 Ödevler

  • [ ] .obs ve Obx kullanarak basit bir sayaç yaz, Get.put()/Get.find() ile controller'a farklı widget'lardan eriş.
  • [ ] Get.to() ile context kullanmadan bir ekran geçişi yap, Navigator.push(context, ...) ile karşılaştır.
  • [ ] Kendi cümlelerinle, GetX'in "context bağımsızlığının" hem avantajını hem potansiyel riskini (encapsulation zayıflığı bağlamında) açıkla.
  • [ ] Provider, Riverpod, BLoC ve GetX'i, "ne zaman hangisini seçerdim" perspektifiyle karşılaştıran kısa bir kişisel not yaz.
  • [ ] Flutter topluluğunda GetX hakkındaki tartışmayı (güncel görüşleri) kısaca araştır, kendi görüşünü oluştur.

Sıradaki konu: Bölüm 6 — Konu 28: Karşılaştırma — Hangi Projede Hangisi? (Bölüm 6'nın Son Konusu)