GetX — ένα ελαφρύ μικρο-πλαίσιο για Flutter που συνδυάζει διαχείριση κατάστασης, πλοήγηση και έγχυση εξαρτήσεων σε ένα πακέτο. Αναπτυγμένο από τον Amir Hossein Abdorashidi, το GetX προσφέρει ελάχιστο boilerplate: χωρίς Stream, χωρίς ChangeNotifier, χωρίς BuildContext για πλοήγηση. Σύμφωνα με δεδομένα του pub.dev, το GetX συγκέντρωσε πάνω από 13 χιλιάδες likes, γινόμενο ένα από τα πιο δημοφιλή πακέτα Flutter.
Κύρια σημεία
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 — το αντιδραστικό widget του GetX που ανακατασκευάζεται όταν αλλάζουν οι Rx-μεταβλητές. Το Obx δεν απαιτεί συνδρομή, dispose ή συναρτήσεις Builder — αρκεί να τυλίξετε το widget σε Obx και να χρησιμοποιήσετε μια Rx-μεταβλητή μέσα. Το Obx παρακολουθεί αυτόματα ποιες Rx-μεταβλητές χρησιμοποιούνται και ανασχεδιάζει μόνο όταν αυτές αλλάζουν.
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 με πολλαπλές εξαρτήσεις.
GetxController — βασική κλάση για επιχειρηματική λογική με υποστήριξη κύκλου ζωής. Το GetxController έχει μεθόδους: onInit() (αρχικοποίηση), onReady() (μετά το πρώτο καρέ), onClose() (καθαρισμός πόρων). Σε αντίθεση με το ChangeNotifier και StateNotifier, το GetxController διαχειρίζεται αυτόματα τις συνδρομές: κατά την καταστροφή της σελίδας, όλες οι Rx-μεταβλητές και Workers διαγράφονται.
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.
// Συνήθης πλοήγηση
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 δημιουργείται μόνο όταν η οθόνη είναι ανοιχτή.
Get.put — εγγραφή στιγμιότυπου στο DI-δοχείο. Get.find — λήψη στιγμιότυπου από το δοχείο. Get.lazyPut — τεμπέλικη αρχικοποίηση (δημιουργείται στην πρώτη κλήση find). Get.putAsync — ασύγχρονη αρχικοποίηση (για υπηρεσίες με init). Get.delete — διαγραφή από το δοχείο (καλείται αυτόματα από τα Bindings κατά την καταστροφή της διαδρομής).
| Μέθοδος | Πότε δημιουργείται | Πότε διαγράφεται |
|---|---|---|
| Get.put | Αμέσως | Get.delete ή onClose |
| Get.lazyPut | Στο πρώτο find | Get.delete ή onClose |
| Get.putAsync | Μετά την εκτέλεση Future | Get.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 βασίζεται σε 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 — μικρο-πλαίσιο με δικό του DI, πλοήγηση και Rx-αντιδραστικότητα. Provider — μόνο διαχείριση κατάστασης μέσω ChangeNotifier και InheritedWidget. Το GetX δεν απαιτεί BuildContext, έχει ενσωματωμένη πλοήγηση και DI, μειώνει το boilerplate κατά 60-70%. Το Provider χρησιμοποιεί τον τυπικό Flutter Navigator και απαιτεί λύσεις τρίτων για DI. Το GetX είναι ταχύτερο στην ανάπτυξη, το Provider — πιο κοντά στο εγγενές Flutter API.
Workers — βοηθήματα για αντιδραστική επεξεργασία αλλαγών Rx-μεταβλητών. ever — callback σε κάθε αλλαγή, once — μόνο στην πρώτη, debounce — με καθυστέρηση (για πεδίο αναζήτησης), interval — όχι συχνότερα από N φορές (για αναλυτικά). Οι Workers δηλώνονται στο onInit() του GetxController και διαγράφονται αυτόματα στο onClose(). Αυτό αντικαθιστά το χειροκίνητο addListener/removeListener με ChangeNotifier.
Το 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 είναι κατάλληλο για έργα οποιουδήποτε μεγέθους, αλλά απαιτεί πειθαρχία. Για μεγάλα έργα (10+ οθόνες) χρησιμοποιήστε: Bindings για απομόνωση Controller, ενότητες (αρχεία GetPages ανά λειτουργικότητα), GetView αντί για χειροκίνητο Get.find στο build. Ο κύριος κίνδυνος — κατάχρηση καθολικής πρόσβασης (Get.find οπουδήποτε). Αυστηρά code review και αρχιτεκτονικές οδηγίες λύνουν αυτό το πρόβλημα. Πολλές εφαρμογές παραγωγής με εκατομμύρια χρήστες λειτουργούν σε GetX.
Bindings — κλάση που συνδέει τη διαδρομή με τις εξαρτήσεις της. Κατά την είσοδο στην οθόνη, το Binding δημιουργεί τον Controller και τις υπηρεσίες μέσω Get.lazyPut, κατά την έξοδο — τα διαγράφει. Τα Bindings υλοποιούν τεμπέλικη αρχικοποίηση: ο Controller δεν υπάρχει στη μνήμη μέχρι να ανοίξει η οθόνη. Αυτό εξοικονομεί RAM και χρόνο εκκίνησης της εφαρμογής. Δηλώνεται στο GetPage: GetPage(name: '/profile', page: () => ProfileScreen(), binding: ProfileBinding()).
Περίληψη
Θα αναπτύξουμε μια εφαρμογή για κινητά έτοιμη για χρήση
Η IT Sectr δημιουργεί εφαρμογές iOS και Android για νεοφυείς επιχειρήσεις και επιχειρήσεις από το 2017. Θα σας συμβουλεύσουμε και θα προτείνουμε την καλύτερη λύση.
Διαβάστε επίσης