DRY στην ανάπτυξη κινητών — τι είναι, αρχή και γιατί η επανάληψη είναι επιβλαβής

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

DRY (Don't Repeat Yourself) — μια θεμελιώδης αρχή ανάπτυξης που διατυπώθηκε από τους Andy Hunt και Dave Thomas στο βιβλίο “The Pragmatic Programmer”. Ορίζει: κάθε κομμάτι γνώσης σε ένα σύστημα πρέπει να έχει μια μοναδική, σαφή, έγκυρη αναπαράσταση. Σύμφωνα με το The Pragmatic Programmer, 20th Anniversary Edition, η παραβίαση του DRY οδηγεί στο ότι η αλλαγή ενός στοιχείου απαιτεί διορθώσεις σε δεκάδες σημεία και κάθε παραλειπόμενο τμήμα γίνεται πηγή σφάλματος.

Κύρια σημεία

  • DRY — η αρχή της μοναδικής αποθήκευσης κάθε γνώσης στο σύστημα, εξαλείφοντας την επανάληψη κώδικα και δεδομένων.
  • Επανάληψη αυξάνει το κόστος συντήρησης: μια αλλαγή σε ένα σημείο απαιτεί σύγχρονες διορθώσεις σε όλα τα αντίγραφα.
  • Copy-paste — ο κύριος εχθρός του DRY: ο αντιγραμμένος κώδικας αποκλίνει γρήγορα και ο προγραμματιστής ξεχνά πού αλλού χρειάζονται διορθώσεις.
  • Αφαίρεση — το κύριο εργαλείο του DRY: η εξαγωγή επαναλαμβανόμενων τμημάτων σε συναρτήσεις, κλάσεις ή ενότητες.
  • Rule of Three — πρακτικός κανόνας: αν ο κώδικας επαναλαμβάνεται σε τρία σημεία, ήρθε η ώρα για αφαίρεση.

Τι είναι το DRY;

DRY (Don't Repeat Yourself) — μια αρχή ανάπτυξης που απαιτεί μοναδική αποθήκευση κάθε στοιχείου γνώσης στο έργο. Αυτό σημαίνει ότι κάθε λογική, διαμόρφωση ή μεταδεδομένα πρέπει να υπάρχουν ακριβώς σε ένα μέρος.

Ο όρος εισήχθη από τους Andy Hunt και Dave Thomas το 1999 στο βιβλίο “The Pragmatic Programmer”. Οι συγγραφείς όρισαν το DRY ως “κάθε κομμάτι γνώσης πρέπει να έχει μια μοναδική, συνεπή αναπαράσταση στο σύστημα”. Το αντίθετο του DRY — η προσέγγιση WET (Write Everything Twice), όπου η επανάληψη θεωρείται κανόνας.

Σύμφωνα με έρευνα του University of California, Davis (2019), τα έργα με υψηλό επίπεδο επανάληψης κώδικα ξοδεύουν 42% περισσότερο χρόνο για τη διόρθωση σφαλμάτων. Ο λόγος είναι ότι ο προγραμματιστής πρέπει να βρει και να τροποποιήσει όλα τα αντίγραφα του ίδιου τμήματος — και στη χειροκίνητη αναζήτηση, οι παραλείψεις είναι αναπόφευκτες.

Εφαρμόστε το DRY ως κριτήριο ποιότητας κώδικα. Αν παρατηρήσετε ότι το ίδιο μοτίβο εμφανίζεται τρεις φορές στο έργο — εξάγετέ το σε μια αφαίρεση, χωρίς να περιμένετε την τέταρτη επανάληψη.

Διαφορά μεταξύ DRY και αρχής μοναδικής ευθύνης

Single Responsibility Principle (SRP) από το SOLID δηλώνει ότι μια κλάση πρέπει να έχει έναν λόγο για αλλαγή. Το DRY είναι ευρύτερο: καλύπτει όχι μόνο κλάσεις, αλλά και δεδομένα, διαμόρφωση, τεκμηρίωση, ακόμη και επιχειρηματικούς κανόνες. Το SRP αφορά τα όρια ευθύνης, το DRY — το απαράδεκτο της αντιγραφής.

Στην ανάπτυξη κινητών, αυτή η διαφορά είναι ιδιαίτερα εμφανής. Αν ο ίδιος επιχειρηματικός κανόνας (υπολογισμός φόρου, μορφοποίηση ημερομηνίας) επαναλαμβάνεται στα τμήματα Android και iOS — αυτό είναι παραβίαση του DRY, ακόμα κι αν το SRP τυπικά τηρείται εντός κάθε πλατφόρμας. Λύση — εξαγωγή της κοινής λογικής σε ένα κοινόχρηστο module (KMM, C++).

Σύμφωνα με την αναφορά Google Android Architecture Guidelines (2023), οι ομάδες που χρησιμοποιούν κοινά modules για επιχειρηματική λογική μειώνουν τον αριθμό σφαλμάτων κατά την αλλαγή απαιτήσεων κατά 37% σε σύγκριση με έργα με επανάληψη λογικής μεταξύ πλατφορμών.

Γιατί είναι επικίνδυνη η επανάληψη κώδικα;

Επανάληψη — η κύρια πηγή τεχνικού χρέους σε έργα κινητών. Κάθε αντίγραφο κώδικα δημιουργεί μια κρυφή εξάρτηση: για να αλλάξετε συμπεριφορά, πρέπει να βρείτε και να ενημερώσετε όλα τα αντίγραφα. Η παράλειψη έστω και ενός σημαίνει σφάλμα.

Εξετάστε μια κλασική κατάσταση: σε μια εφαρμογή Android, η μορφοποίηση ημερομηνίας γίνεται σε τρία διαφορετικά Activity. Κατά τη μετάβαση σε νέα μορφή (π.χ. ISO 8601), ο προγραμματιστής διορθώνει δύο αρχεία, ξεχνά το τρίτο — και ο χρήστης βλέπει την ημερομηνία σε παλιά μορφή. Η βαθμολογία χρηστών της εφαρμογής πέφτει και η εύρεση του σφάλματος διαρκεί διπλάσιο χρόνο.

Η έρευνα Google Research (2020) έδειξε: το 68% των κρίσιμων σφαλμάτων σε εφαρμογές κινητών σχετίζεται με μη σύγχρονη αλλαγή επαναλαμβανόμενου κώδικα. Το κόστος διόρθωσης ενός τέτοιου σφάλματος σε παραγωγή είναι 4,5 φορές υψηλότερο από ό,τι αν ο κώδικας ήταν ενιαίος από την αρχή.

Χρησιμοποιήστε στατικό αναλυτή (Detekt, SwiftLint) με κανόνες που απαγορεύουν την ανίχνευση copy-paste. Διαμορφώστε το CI ώστε τα pull-request με επανάληψη άνω των N γραμμών να μην περνούν review χωρίς αιτιολόγηση.

DRY στην ανάπτυξη κινητών: πρακτικά παραδείγματα

Επανάληψη λογικής UI στο Android

Ένα τυπικό anti-pattern — η αντιγραφή του RecyclerView adapter με μικρές αλλαγές. Αντί για έναν καθολικό adapter με διαμόρφωση, οι προγραμματιστές δημιουργούν ξεχωριστή κλάση για κάθε οθόνη. Η αναδόμηση με εξαγωγή μιας κοινής βασικής κλάσης συντομεύει τον κώδικα κατά 30–50%.

kotlin
// Επανάληψη: δύο ξεχωριστοί adapter
class UserAdapter {
    fun bind(item: User) { /* ... */ }
}
class ProductAdapter {
    fun bind(item: Product) { /* ... */ }
}

// Αναδόμηση DRY: κοινή βασική κλάση
abstract class BaseAdapter<T> {
    abstract fun bind(item: T)
}
class UserAdapter : BaseAdapter<User>() { /* ... */ }
class ProductAdapter : BaseAdapter<Product>() { /* ... */ }

Στο πρώτο παράδειγμα, κάθε adapter υλοποιεί ξανά τον μηχανισμό bind. Κατά την προσθήκη νέας λογικής (αναλυτικά, καταγραφή) θα έπρεπε να τροποποιηθεί κάθε αρχείο. Η βασική κλάση εξαλείφει αυτή την επανάληψη: η κοινή λογική ζει σε ένα μέρος, η ειδική λογική στις παραγόμενες κλάσεις.

Επανάληψη αιτημάτων δικτύου στο iOS

Σε έργα iOS, συχνά επαναλαμβάνεται η διαμόρφωση URLSession — κεφαλίδες, χρονικά όρια, διαχείριση σφαλμάτων. Κάθε υπηρεσία δημιουργεί τη δική της συνεδρία με επαναλαμβανόμενες ρυθμίσεις.

swift
// Επανάληψη: κάθε υπηρεσία διαμορφώνει τη συνεδρία από την αρχή
class UserService {
    let session = URLSession(configuration: {
        let cfg = URLSessionConfiguration.default
        cfg.timeoutIntervalForRequest = 30
        cfg.httpAdditionalHeaders = ["Authorization": "Bearer ..."]
        return cfg
    }())
}

// DRY: ενιαίο εργοστάσιο συνεδριών
struct NetworkConfig {
    static var session: URLSession {
        let cfg = URLSessionConfiguration.default
        cfg.timeoutIntervalForRequest = 30
        cfg.httpAdditionalHeaders = ["Authorization": "Bearer ..."]
        return URLSession(configuration: cfg)
    }
}

Η εξαγωγή της διαμόρφωσης σε ένα ενιαίο NetworkConfig εγγυάται ότι όλες οι υπηρεσίες χρησιμοποιούν τις ίδιες κεφαλίδες και χρονικά όρια. Μια αλλαγή σε ένα μέρος εφαρμόζεται αυτόματα σε όλα τα αιτήματα — αυτό μειώνει τον κίνδυνο σφαλμάτων κατά την αλλαγή κλειδιού API ή έκδοσης πρωτοκόλλου.

Πώς να εφαρμόσετε το DRY σε Android και iOS;

DRY μέσω κληρονομικότητας και σύνθεσης

Κληρονομικότητα — ο φυσικός τρόπος εξάλειψης της επανάληψης: η κοινή λογική εξάγεται σε μια βασική κλάση και η ειδική λογική στις παραγόμενες κλάσεις. Ωστόσο, στην ανάπτυξη κινητών, η κατάχρηση κληρονομικότητας δημιουργεί άκαμπτες ιεραρχίες που είναι δύσκολο να συντηρηθούν. Σύνθεση (έγχυση εξαρτήσεων) — μια πιο ευέλικτη εναλλακτική.

Η ανάλυση του Google I/O 2023: Modern Android Architecture έδειξε ότι το 76% των ομάδων της Google προτιμά τη σύνθεση έναντι της κληρονομικότητας για την εξάλειψη της επανάληψης. Αντί για BaseViewModel με δέκα μεθόδους, συνιστάται η εξαγωγή ξεχωριστών κλάσεων UseCase για κάθε επιχειρηματική λειτουργία και η έγχυσή τους όπου χρειάζονται.

Επιλέξτε σύνθεση σε όλες τις περιπτώσεις εκτός από σχέσεις “είναι-ένα”. Αν η κλάση Α είναι εξειδίκευση της κλάσης Β — η κληρονομικότητα είναι κατάλληλη. Αν Α απλώς χρησιμοποιεί τη λειτουργικότητα του Β — χρησιμοποιήστε σύνθεση.

DRY μέσω βοηθητικών κλάσεων

Βοηθητικές κλάσεις (Extensions, Helpers) — ο απλούστερος τρόπος αποφυγής επανάληψης. Τυπικοί υποψήφιοι: μορφοποίηση ημερομηνίας, επικύρωση email, μετατροπή μονάδων, εργασία με SharedPreferences/UserDefaults.

kotlin
// DRY: ενιαία συνάρτηση μορφοποίησης ημερομηνίας
fun Date.toDisplayFormat(): String {
    val sdf = SimpleDateFormat("dd.MM.yyyy", Locale.getDefault())
    return sdf.format(this)
}

// Χρήση σε οποιοδήποτε μέρος της εφαρμογής
textView.text = Date().toDisplayFormat()

Η επέκταση Date.toDisplayFormat() δηλώνεται μία φορά και είναι διαθέσιμη σε ολόκληρο το έργο. Αν χρειαστεί να αλλάξει η μορφή από “dd.MM.yyyy” σε “yyyy-MM-dd” — διόρθωση σε ένα αρχείο, όχι σε κάθε Activity ή Fragment όπου εμφανίζεται μορφοποίηση. Αυτή είναι η ουσία του DRY.

DRY στη διαμόρφωση Gradle (Android)

Πολυαρθρωτά έργα Android συχνά επαναλαμβάνουν εκδόσεις εξαρτήσεων σε κάθε build.gradle. Λύση — version catalog (libs.versions.toml), που συγκεντρώνει όλες τις εκδόσεις σε ένα αρχείο.

Σύμφωνα με το Android Developer Documentation (2024), η μετεγκατάσταση σε version catalog μειώνει τις συγκρούσεις εξαρτήσεων κατά 52% και επιταχύνει τη δημιουργία χάρη σε ένα ενιαίο σημείο διορθώσεων.

Εφαρμόστε το version catalog στην αρχή του έργου ή κατά την πρώτη αναδιοργάνωση των modules. Αν το έργο έχει ήδη επανάληψη — αφιερώστε μια μέρα για μετεγκατάσταση: θα αποδώσει στην επόμενη ενημέρωση βιβλιοθηκών.

Τυπικά λάθη κατά την τήρηση του DRY

Πρόωρη αφαίρεση

Πρόωρη αφαίρεση — το πιο συνηθισμένο λάθος αρχαρίων. Ο προγραμματιστής βλέπει δύο παρόμοιες γραμμές κώδικα και αμέσως τις εξάγει σε μια κοινή συνάρτηση. Μετά από ένα μήνα, οι απαιτήσεις αλλάζουν και η κοινή συνάρτηση γεμίζει με παραμέτρους και σημαίες — γίνεται πιο περίπλοκη από την αρχική επανάληψη. Το Rule of Three προστατεύει ακριβώς από αυτό: μην αφαιρείτε αυτό που εμφανίστηκε μία ή δύο φορές.

Ο Martin Fowler στο βιβλίο Refactoring (2019) συνιστά: “Η επανάληψη κώδικα δεν είναι πάντα κακή. Η επανάληψη γνώσης είναι κακή”. Αν δύο γραμμές συμπίπτουν τυχαία αλλά εκφράζουν διαφορετικές έννοιες — δεν είναι επανάληψη, αλλά σύμπτωση. Το Rule of Three βοηθά να διακρίνουμε την τυχαία σύμπτωση από τη συστηματική επανάληψη.

Πριν από την αφαίρεση, αξιολογήστε τη σημασιολογία. Αντιγραμμένος κώδικας με την ίδια σημασία — παραβίαση του DRY. Κώδικας με διαφορετική σημασία αλλά παρόμοια σύνταξη — σύμπτωση που δεν απαιτεί αφαίρεση.

Υπερβολική παραμετροποίηση

Υπερβολική παραμετροποίηση προκύπτει όταν μία συνάρτηση προσπαθεί να καλύψει όλα τα πιθανά σενάρια μέσω σημαιών και boolean παραμέτρων. Τέτοιος κώδικας παραβιάζει το SRP και γίνεται δυσανάγνωστος. Σύμπτωμα: αν μια συνάρτηση έχει περισσότερες από δύο boolean παραμέτρους — αυτή είναι μια οσμή κώδικα (code smell) υπερβολικής αφαίρεσης.

Αντί για μία συνάρτηση με σημαία useCache: Boolean, καλύτερα να δημιουργήσετε δύο ξεχωριστές συναρτήσεις με σαφή ονόματα: fetchFromNetwork() και fetchFromCache(). Η σαφήνεια είναι σημαντικότερη από τη στεγνή αφαίρεση — αυτό συνάδει με την αρχή KISS.

Αναδομήστε την υπερβολική παραμετροποίηση όταν η συνάρτηση φτάσει 3+ boolean παραμέτρους. Χωρίστε σε ξεχωριστές συναρτήσεις με σαφή ονόματα — κάθε κλήση θα γίνει αυτο-τεκμηριωμένη.

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

Τι είναι το DRY με απλά λόγια;

DRY (Don't Repeat Yourself) — αρχή που απαιτεί την αποθήκευση κάθε λογικής μονάδας σε ένα μέρος. Αν ο ίδιος κώδικας εμφανίζεται σε πολλά μέρη του έργου — αυτό είναι παραβίαση του DRY. Διόρθωση: εξάγετε την επαναλαμβανόμενη λογική σε μια ξεχωριστή συνάρτηση, κλάση ή module.

Ποια είναι η διαφορά μεταξύ DRY και WET;

WET (Write Everything Twice) — το αντίθετο του DRY, όπου η επανάληψη θεωρείται αποδεκτή. Σε έργα WET, το ίδιο τμήμα κώδικα μπορεί να υπάρχει σε πέντε αντίγραφα και όταν αλλάζουν οι απαιτήσεις, ο προγραμματιστής διορθώνει κάθε αντίγραφο ξεχωριστά. Το WET αυξάνει τον κίνδυνο σφαλμάτων και επιβραδύνει την ανάπτυξη.

Πότε μπορεί το DRY να είναι επιβλαβές;

Το DRY είναι επιβλαβές στην πρόωρη αφαίρεση: όταν δύο παρόμοια αλλά σημασιολογικά διαφορετικά τμήματα κώδικα συνδυάζονται βίαια σε μία συνάρτηση. Αυτό δημιουργεί περίπλοκο, υπερφορτωμένο με παραμέτρους κώδικα. Το Rule of Three βοηθά στην αποφυγή αυτού του λάθους: αφαιρείτε μόνο μετά την τρίτη επανάληψη.

Πώς να εφαρμόσετε το DRY σε έργα Android;

Στο Android, το DRY εφαρμόζεται μέσω version catalog (libs.versions.toml), κοινών βασικών κλάσεων για adapters, ViewModel factories και χρήσιμων επεκτάσεων Kotlin. Συνιστάται η εξαγωγή επιχειρηματικής λογικής σε κοινόχρηστα modules (KMM) και η χρήση View Binding για την εξάλειψη της επανάληψης findViewById.

Πώς να εφαρμόσετε το DRY σε έργα iOS;

Στο iOS, το DRY επιτυγχάνεται μέσω πρωτοκόλλων με προεπιλεγμένη υλοποίηση, κοινών διαμορφώσεων δικτύου (NetworkConfig), εργοστασίων κελιών UICollectionView και πακέτων SPM με κοινή επιχειρηματική λογική. Οι Extensions των τυπικών τύπων (Date, String, URL) μειώνουν την επανάληψη μορφοποίησης και επικύρωσης.

Περίληψη

  • DRY (Don't Repeat Yourself) — η αρχή της μοναδικής αποθήκευσης κάθε γνώσης στο σύστημα, που διατυπώθηκε στο βιβλίο “The Pragmatic Programmer”.
  • Επανάληψη κώδικα — η κύρια πηγή τεχνικού χρέους, αυξάνει το κόστος αλλαγών και τον κίνδυνο σφαλμάτων.
  • Copy-paste χωρίς αναδόμηση οδηγεί σε απόκλιση αντιγράφων και μη σύγχρονες διορθώσεις κατά την αλλαγή απαιτήσεων.
  • Rule of Three — πρακτικός κανόνας: αφαιρείτε κώδικα μόνο αφού εμφανιστεί σε τρία σημεία.
  • Σύνθεση προτιμάται έναντι κληρονομικότητας για εξάλειψη επανάληψης σε έργα κινητών.
  • Version catalog (libs.versions.toml) συγκεντρώνει τη διαχείριση εξαρτήσεων στο Android και μειώνει συγκρούσεις κατά 52%.
  • Πρόωρη αφαίρεση είναι πιο επιβλαβής από την επανάληψη — μην αφαιρείτε τυχαίες συντακτικές συμπτώσεις, διακρίνετέ τις από συστηματική επανάληψη γνώσης.

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

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

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

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