GetX: βασικές έννοιες, πλοήγηση και DI στο Flutter

Συγγραφέας: IT Sectr Δημοσιεύτηκε: 2026-02-19 Χρόνος ανάγνωσης: 7 λεπ

GetX — ένα ελαφρύ μικρο-πλαίσιο για Flutter που συνδυάζει διαχείριση κατάστασης, πλοήγηση και έγχυση εξαρτήσεων σε ένα πακέτο. Αναπτυγμένο από τον Amir Hossein Abdorashidi, το GetX προσφέρει ελάχιστο boilerplate: χωρίς Stream, χωρίς ChangeNotifier, χωρίς BuildContext για πλοήγηση. Σύμφωνα με δεδομένα του pub.dev, το GetX συγκέντρωσε πάνω από 13 χιλιάδες likes, γινόμενο ένα από τα πιο δημοφιλή πακέτα Flutter.

Κύρια σημεία

  • Obx — αντιδραστικό widget που ανακατασκευάζεται όταν αλλάζει η Rx-μεταβλητή
  • GetController — κλάση επιχειρηματικής λογικής με μεθόδους και Rx-μεταβλητές
  • Get.to — πλοήγηση χωρίς BuildContext μέσω ονομασμένων διαδρομών
  • Get.put / Get.find — έγχυση και λήψη εξαρτήσεων μέσω DI-δοχείου
  • Rx-μεταβλητές — αντιδραστικά περιτυλίγματα (RxInt, RxString, RxBool) με αυτόματη ειδοποίηση

Τι είναι το GetX;

GetX — ένα all-in-one μικρο-πλαίσιο για Flutter που λύνει τρεις κύριες εργασίες ανάπτυξης: διαχείριση κατάστασης (State Management), πλοήγηση (Routing) και έγχυση εξαρτήσεων (DI). Το GetX δεν απαιτεί Stream, ChangeNotifier, Builders ή συνδρομές — όλη η αντιδραστικότητα παρέχεται από Rx-περιτυλίγματα βασισμένα σε GetValue και GetStream, που λειτουργούν δεκάδες φορές γρηγορότερα από το ChangeNotifier.

Το GetX τοποθετείται ως εναλλακτική του συνδυασμού Provider + Navigator + get_it/kiwi. Αντί να εγκαταστήσετε τρία διαφορετικά πακέτα και να γράψετε 10 γραμμές διαμόρφωσης, το GetX δίνει τα πάντα από ένα κουτί με μία γραμμή: GetMaterialApp αντί για MaterialApp. Η πλοήγηση λειτουργεί μέσω Get.to(NextScreen()) χωρίς BuildContext, και η DI — μέσω Get.put(Service()) χωρίς δέντρο Provider.

Σύμφωνα με το Flutter Community Survey 2025, το GetX χρησιμοποιείται στο 43% των Flutter έργων. Κύριοι λόγοι επιλογής: ελάχιστο όριο εισόδου (5 λεπτά για εκμάθηση), απουσία boilerplate (ο κώδικας μικραίνει κατά 60-70% σε σύγκριση με Provider ή BLoC) και γρήγορη ανάπτυξη MVP. Οι επικριτές αναφέρουν παραβίαση της αρχής διαχωρισμού ευθυνών και δυσκολία εντοπισμού σφαλμάτων.

Αντιδραστική κατάσταση: Obx και Rx

Obx — το αντιδραστικό widget του GetX που ανακατασκευάζεται όταν αλλάζουν οι Rx-μεταβλητές. Το Obx δεν απαιτεί συνδρομή, dispose ή συναρτήσεις Builder — αρκεί να τυλίξετε το widget σε Obx και να χρησιμοποιήσετε μια Rx-μεταβλητή μέσα. Το Obx παρακολουθεί αυτόματα ποιες Rx-μεταβλητές χρησιμοποιούνται και ανασχεδιάζει μόνο όταν αυτές αλλάζουν.

Dart
class CounterController extends GetxController {
  final count = 0.obs;
  void increment() => count++;
}

class CounterScreen extends StatelessWidget {
  final controller = Get.put(CounterController());

  @override
  Widget build(context) => Obx(() => Text('${controller.count}'));
}

Rx-μεταβλητές: .obs — getter που τυλίγει οποιαδήποτε τιμή σε ένα Rx-αντικείμενο. Το GetX παρέχει τυποποιημένες Rx-κλάσεις: RxInt, RxString, RxDouble, RxBool, RxList, RxMap. Όλες οι Rx-μεταβλητές συμπεριφέρονται όπως συνηθισμένα πρωτογενή: count++, name.value = 'Hello', items.add(item). Η αλλαγή ειδοποιεί αυτόματα τους συνδρομητές Obx.

GetBuilder — εναλλακτική του Obx χωρίς Rx, που λειτουργεί μέσω χειροκίνητης κλήσης update(). GetBuilder.filter — για σημειακή ενημέρωση βάσει κλειδιών ID. Το Obx είναι ταχύτερο (αυτόματη παρακολούθηση εξαρτήσεων), το GetBuilder πιο προβλέψιμο (ρητή κλήση ενημέρωσης). Το Obx συνιστάται για απλά σενάρια και το GetBuilder για σύνθετα widget με πολλαπλές εξαρτήσεις.

GetController και κύκλος ζωής

GetxController — βασική κλάση για επιχειρηματική λογική με υποστήριξη κύκλου ζωής. Το GetxController έχει μεθόδους: onInit() (αρχικοποίηση), onReady() (μετά το πρώτο καρέ), onClose() (καθαρισμός πόρων). Σε αντίθεση με το ChangeNotifier και StateNotifier, το GetxController διαχειρίζεται αυτόματα τις συνδρομές: κατά την καταστροφή της σελίδας, όλες οι Rx-μεταβλητές και Workers διαγράφονται.

Dart
class AuthController extends GetxController {
  final user = Rx<User?>(null);
  final isLoading = false.obs;

  @override
  void onInit() {
    ever(isLoading, (_) => print('Loading: $isLoading'));
    super.onInit();
  }

  Future<void> login(String email, String password) async {
    isLoading.value = true;
    user.value = await api.login(email, password);
    isLoading.value = false;
  }
}

Workers — αντιδραστικά βοηθήματα του GetX: ever (καλείται σε κάθε αλλαγή), once (μόνο στην πρώτη αλλαγή), debounce (με καθυστέρηση), interval (όχι συχνότερα από N φορές το δευτερόλεπτο). Οι Workers λύνουν τυπικές εργασίες: επικύρωση πεδίου (debounce), αναλυτικά (once), συγχρονισμός (ever). Οι Workers διαγράφονται αυτόματα κατά την κλήση onClose(), αποτρέποντας διαρροές μνήμης.

Πλοήγηση GetX δεν απαιτεί BuildContext για μετάβαση μεταξύ οθονών. Αντί για Navigator.push(context, MaterialPageRoute(...)) χρησιμοποιείται Get.to(NextScreen()) — κλήση από οπουδήποτε, συμπεριλαμβανομένου του Controller χωρίς πρόσβαση σε BuildContext. Το GetX υποστηρίζει ονομασμένες διαδρομές, κινούμενα σχέδια, middleware και μεταφορά ορισμάτων χωρίς MaterialPageRoute.

Dart
// Συνήθης πλοήγηση
Get.to(ProfileScreen());
Get.back();
Get.off(LoginScreen()); // αντικατάσταση τρέχουσας διαδρομής
Get.offAll(HomeScreen()); // εκκαθάριση στοίβας

// Ονομασμένες διαδρομές
Get.toNamed('/profile', arguments: 'user123');
Get.offNamed('/login');

// Middleware
GetPage(
  name: '/profile',
  page: () => ProfileScreen(),
  middlewares: [AuthMiddleware()],
)

GetPage και GetPages: Το GetX χρησιμοποιεί GetPages αντί για routes στο MaterialApp. Middleware — έλεγχος εξουσιοδότησης, ανακατευθύνσεις, αναλυτικά πριν την είσοδο στην οθόνη. Transition — ενσωματωμένα κινούμενα σχέδια μετάβασης: fadeIn, zoom, leftToRight, topToBottom. Bindings — κλάση που αρχικοποιεί τον Controller και τις εξαρτήσεις κατά την είσοδο στη διαδρομή. Τα Bindings λύνουν το πρόβλημα της τεμπέλικης αρχικοποίησης: ο Controller δημιουργείται μόνο όταν η οθόνη είναι ανοιχτή.

Έγχυση εξαρτήσεων με GetX

Get.put — εγγραφή στιγμιότυπου στο DI-δοχείο. Get.find — λήψη στιγμιότυπου από το δοχείο. Get.lazyPut — τεμπέλικη αρχικοποίηση (δημιουργείται στην πρώτη κλήση find). Get.putAsync — ασύγχρονη αρχικοποίηση (για υπηρεσίες με init). Get.delete — διαγραφή από το δοχείο (καλείται αυτόματα από τα Bindings κατά την καταστροφή της διαδρομής).

ΜέθοδοςΠότε δημιουργείταιΠότε διαγράφεται
Get.putΑμέσωςGet.delete ή onClose
Get.lazyPutΣτο πρώτο findGet.delete ή onClose
Get.putAsyncΜετά την εκτέλεση FutureGet.delete ή onClose
Get.createΣε κάθε find (νέο εργοστάσιο)Όχι

GetX DI — το απλούστερο DI-δοχείο στο Flutter. Χωρίς δέντρο Provider, χωρίς Module, χωρίς Scope. Το Get.put(Repository()) στον Controller ή στο main.dart καθιστά το αντικείμενο διαθέσιμο οπουδήποτε στην εφαρμογή μέσω Get.find<Repository>(). Το GetX DI υποστηρίζει επίσης επισήμανση (tag: 'api') και μονιμότητα (permanent: true) για αποτροπή διαγραφής.

GetX: best practices και απόδοση

Η απόδοση του GetX βασίζεται σε Rx-περιτυλίγματα που λειτουργούν μέσω GetStream — μιας ιδιόκτητης υλοποίησης Stream βελτιστοποιημένης για Flutter. Σύμφωνα με τα benchmark του GetX, οι Rx-μεταβλητές είναι 2-3 φορές ταχύτερες από το ChangeNotifier και 5-7 φορές ταχύτερες από το BLoC σε συχνές ενημερώσεις (30+ fps). Το GetX δεν χρησιμοποιεί BuildContext για συνδρομές, εξαλείφοντας την ανακατασκευή του δέντρου widget κατά την πλοήγηση.

Best practices: χρησιμοποιήστε GetBuilder αντί για Obx για widget με μεγάλο αριθμό θυγατρικών στοιχείων (λίστες, πίνακες). Διαχωρίστε τους Controller ανά λειτουργικές μονάδες, όχι έναν τεράστιο Controller ανά σελίδα. Χρησιμοποιήστε Bindings για αρχικοποίηση Controller, όχι Get.put στη μέθοδο build. GetView — ένας συντομευμένος StatelessWidget με πρόσβαση στον Controller μέσω controller χωρίς Get.find.

Γνωστοί περιορισμοί: Το GetX χρησιμοποιεί καθολικές μεταβλητές (Get.find, Get.to), που μπορεί να δυσκολέψει τη δοκιμή. Η υποβολή mock εξαρτήσεων μέσω GetX απαιτεί Get.replace() ή Get.reset() μεταξύ δοκιμών. Για απομόνωση, συνιστάται Get.testMode = true. Το GetX δεν συνιστάται για εφαρμογές που απαιτούν αυστηρή αρχιτεκτονική με σαφή όρια επιπέδων — σε αυτήν την περίπτωση, το BLoC ή το Riverpod με δημιουργία κώδικα είναι προτιμότερα.

Συχνές Ερωτήσεις

Σε τι διαφέρει το GetX από το Provider;

GetX — μικρο-πλαίσιο με δικό του DI, πλοήγηση και Rx-αντιδραστικότητα. Provider — μόνο διαχείριση κατάστασης μέσω ChangeNotifier και InheritedWidget. Το GetX δεν απαιτεί BuildContext, έχει ενσωματωμένη πλοήγηση και DI, μειώνει το boilerplate κατά 60-70%. Το Provider χρησιμοποιεί τον τυπικό Flutter Navigator και απαιτεί λύσεις τρίτων για DI. Το GetX είναι ταχύτερο στην ανάπτυξη, το Provider — πιο κοντά στο εγγενές Flutter API.

Τι είναι τα GetX Workers;

Workers — βοηθήματα για αντιδραστική επεξεργασία αλλαγών Rx-μεταβλητών. ever — callback σε κάθε αλλαγή, once — μόνο στην πρώτη, debounce — με καθυστέρηση (για πεδίο αναζήτησης), interval — όχι συχνότερα από N φορές (για αναλυτικά). Οι Workers δηλώνονται στο onInit() του GetxController και διαγράφονται αυτόματα στο onClose(). Αυτό αντικαθιστά το χειροκίνητο addListener/removeListener με ChangeNotifier.

Πώς δοκιμάζουμε το GetX;

Το GetX παρέχει Get.testMode = true για ενεργοποίηση λειτουργίας δοκιμής. Οι εξαρτήσεις αντικαθίστανται μέσω Get.replace<Service>(mockService). Μεταξύ δοκιμών καλείται Get.reset() για καθαρισμό του DI-δοχείου. Οι Controller δοκιμάζονται απευθείας χωρίς Flutter: final c = CounterController(); c.increment(); expect(c.count.value, 1). Για widget με Obx, χρησιμοποιήστε tester.pumpWidget με InjectMocker.

Αξίζει να χρησιμοποιήσουμε GetX για μεγάλα έργα;

Το GetX είναι κατάλληλο για έργα οποιουδήποτε μεγέθους, αλλά απαιτεί πειθαρχία. Για μεγάλα έργα (10+ οθόνες) χρησιμοποιήστε: Bindings για απομόνωση Controller, ενότητες (αρχεία GetPages ανά λειτουργικότητα), GetView αντί για χειροκίνητο Get.find στο build. Ο κύριος κίνδυνος — κατάχρηση καθολικής πρόσβασης (Get.find οπουδήποτε). Αυστηρά code review και αρχιτεκτονικές οδηγίες λύνουν αυτό το πρόβλημα. Πολλές εφαρμογές παραγωγής με εκατομμύρια χρήστες λειτουργούν σε GetX.

Τι είναι τα GetX Bindings;

Bindings — κλάση που συνδέει τη διαδρομή με τις εξαρτήσεις της. Κατά την είσοδο στην οθόνη, το Binding δημιουργεί τον Controller και τις υπηρεσίες μέσω Get.lazyPut, κατά την έξοδο — τα διαγράφει. Τα Bindings υλοποιούν τεμπέλικη αρχικοποίηση: ο Controller δεν υπάρχει στη μνήμη μέχρι να ανοίξει η οθόνη. Αυτό εξοικονομεί RAM και χρόνο εκκίνησης της εφαρμογής. Δηλώνεται στο GetPage: GetPage(name: '/profile', page: () => ProfileScreen(), binding: ProfileBinding()).

Περίληψη

  • GetX — Flutter μικρο-πλαίσιο με διαχείριση κατάστασης, πλοήγηση και DI σε ένα πακέτο
  • Obx και Rx — αντιδραστικά περιτυλίγματα με αυτόματη ανασχεδίαση χωρίς Stream και ChangeNotifier
  • GetxController — κλάση επιχειρηματικής λογικής με κύκλο ζωής onInit/onReady/onClose
  • Get.to / Get.back — πλοήγηση χωρίς BuildContext με ενσωματωμένα κινούμενα σχέδια
  • Get.put / Get.find — DI-δοχείο χωρίς δέντρο Provider με τεμπέλικη αρχικοποίηση
  • Workers — ever, once, debounce, interval για αντιδραστική επεξεργασία αλλαγών
  • Bindings — τεμπέλικη αρχικοποίηση Controller κατά το άνοιγμα διαδρομής με αυτόματη διάθεση

Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση

Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.

Συζήτηση έργου

Διαβάστε επίσης