Frankenstein στον προγραμματισμό — τι είναι, αιτίες και πρόληψη

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

Frankenstein στον προγραμματισμό είναι κώδικας που συναρμολογείται από ασύμβατα μέρη διαφορετικών τεχνολογιών, στυλ και αρχιτεκτονικών. Σύμφωνα με έρευνα του ThoughtWorks Technology Radar (2024), το 28% των μεγάλων έργων εμφανίζει σημάδια του συνδρόμου Frankenstein — αρχιτεκτονικού εκλεκτικισμού που προκύπτει όταν απουσιάζει ένα ενιαίο τεχνικό όραμα. Κατ’ αναλογία με το μυθιστόρημα της Mary Shelley, τέτοιος κώδικας λειτουργεί, αλλά η συντήρησή του γίνεται εφιάλτης.

Κύρια σημεία

  • Frankenstein — ένα αντι-πρότυπο όπου το σύστημα συναρμολογείται από ετερογενή, κακώς συμβατά στοιχεία
  • Κύριες αιτίες: απουσία αρχιτέκτονα, συγχώνευση έργων, “dημιουργικότητα χωρίς όρια”
  • Το πρόβλημα — κάθε στοιχείο απαιτεί γνώση της δικής του τεχνολογίας και η αλληλεπίδραση είναι απρόβλεπτη
  • Η αναδόμηση του Frankenstein απαιτεί ενοποίηση της τεχνολογικής στοίβας και καθορισμό σαφών ορίων
  • Architecture Decision Records και RFC — τα καλύτερα εργαλεία πρόληψης

Τι είναι το Frankenstein στον προγραμματισμό

Frankenstein (Frankenstein code, Frankenstein pattern) είναι ένα αντι-πρότυπο όπου ένα σύστημα λογισμικού συναρμολογείται από μέρη που δεν έχουν σχεδιαστεί να λειτουργούν μαζί. Όπως το τέρας του Frankenstein, τέτοιος κώδικας μπορεί να λειτουργεί, αλλά είναι άσχημος, απρόβλεπτος και επικίνδυνος στις παραμικρές αλλαγές.

Ο όρος προέρχεται από τη λογοτεχνία: στο μυθιστόρημα Mary Shelley “Frankenstein, or the Modern Prometheus” (1818), ένας επιστήμονας δημιούργησε ένα ζωντανό ον από θραύσματα σωμάτων διαφορετικών νεκρών ανθρώπων. Στον προγραμματισμό, η αναλογία είναι ακριβής — οι προγραμματιστές παίρνουν κομμάτια διαφορετικών frameworks, βιβλιοθηκών, γλωσσών και τα κολλούν μαζί, με αποτέλεσμα ένα λειτουργικό αλλά τερατώδες αποτέλεσμα.

Η διαφορά του Frankenstein από τον μακαρονάδικο κώδικα (spaghetti code) βρίσκεται στην κλίμακα και τη φύση του προβλήματος. Ο μακαρονάδικος κώδικας είναι μια μπερδεμένη δομή μέσα σε μία τεχνολογική στοίβα. Ο Frankenstein είναι εκλεκτικισμός σε επίπεδο αρχιτεκτονικής: διαφορετικές τεχνολογίες, ασύμβατα παραδείγματα, αντικρουόμενες προσεγγίσεις μέσα σε ένα σύστημα.

Frankenstein vs μικρουπηρεσίες

Η αρχιτεκτονική μικρουπηρεσιών επιτρέπει τη χρήση διαφορετικών τεχνολογιών για διαφορετικές υπηρεσίες, αλλά υπό την προϋπόθεση σαφών ορίων και τυποποιημένων πρωτοκόλλων επικοινωνίας. Ο Frankenstein είναι χαοτική ανάμειξη χωρίς όρια: REST και GraphQL στον ίδιο ελεγκτή, δύο ORM στο ίδιο module, SQL και NoSQL για την ίδια οντότητα.

Γιατί εμφανίζεται το σύνδρομο Frankenstein

Η απουσία τεχνικού ηγέτη ή αρχιτέκτονα είναι η βασική αιτία. Όταν σε ένα έργο δεν υπάρχει κάποιος υπεύθυνος για την ακεραιότητα της αρχιτεκτονικής, κάθε προγραμματιστής επιλέγει εργαλεία “για τον εαυτό του”. Ο ένας προτιμά το Spring, ο δεύτερος το Guice, ο τρίτος μια δική του υλοποίηση DI. Το αποτέλεσμα είναι ένα αρχιτεκτονικό συνονθύλευμα.

Η συγχώνευση έργων είναι η δεύτερη συνηθισμένη αιτία. Δύο ομάδες ανέπτυξαν ανεξάρτητα τα modules τους χρησιμοποιώντας διαφορετικές στοίβες. Όταν τα modules πρέπει να ενωθούν σε μία εφαρμογή, απλώς “κολλούνται” με προσαρμογείς και ενδιάμεσα επίπεδα. Το αποτέλεσμα είναι Frankenstein.

Οι εταιρικές εξαγορές είναι το τρίτο σενάριο. Η εταιρεία Α αγόρασε την εταιρεία Β και θέλει να ενσωματώσει το προϊόν της στο δικό της. Αντί για επαναγραφή — κόλλημα μέσω API, κοινές βάσεις δεδομένων και λύσεις ανάγκης. Σε ένα χρόνο, το σύστημα γίνεται ένα τέρας που κανείς δεν καταλαβαίνει.

ΑιτίαΠεριγραφήΤυπικό αποτέλεσμα
Χωρίς αρχιτέκτοναΚάθε προγραμματιστής επιλέγει τη δική του στοίβα3 διαφορετικοί HTTP πελάτες σε ένα module
Συγχώνευση έργωνΔύο προϊόντα συγχωνεύονται σε έναΔύο ORM, δύο τρόποι καταγραφής
ΕξαγορέςΕξαγορά εταιρείας με το προϊόν τηςΥβρίδιο διαφορετικών αρχιτεκτονικών και στυλ
ΠειράματαΕισαγωγή νέων τεχνολογιών χωρίς στρατηγικήJava 8 + Java 21 χαρακτηριστικά στο ίδιο αρχείο
Πολιτικές αποφάσειςΕπιβολή τεχνολογίας από πάνω χωρίς συμφραζόμεναEnterprise framework για απλό script

Ο παράγοντας “dημιουργικότητας”

Έμπειροι προγραμματιστές που θέλουν να δοκιμάσουν νέες τεχνολογίες σε παραγωγή συχνά γίνονται πηγή του Frankenstein. Αντί να περιορίζουν τα πειράματα σε ένα απομονωμένο module, εισάγουν πειραματικό κώδικα σε κρίσιμο μέρος του συστήματος.

Παραδείγματα Frankenstein σε πραγματικά έργα

Κλασικό παράδειγμα είναι η χρήση πολλαπλών ORM σε μία εφαρμογή. Μερικά modules χρησιμοποιούν Hibernate, άλλα MyBatis, και άλλα άμεσα ερωτήματα JDBC. Οι συναλλαγές γίνονται μη διαχειρίσιμες, η προσωρινή μνήμη ασυνεπής, και ο νέος προγραμματιστής δεν ξέρει ποια προσέγγιση να επιλέξει για μια νέα λειτουργία.

Δεύτερο παράδειγμα είναι η ανάμειξη αρχιτεκτονικών στυλ. Σε έναν ελεγκτή REST API υπάρχουν κλήσεις υπηρεσιών SOAP, άμεσα ερωτήματα SQL, πρόσβαση στο σύστημα αρχείων και δημιουργία HTML. Μια τέτοια εφαρμογή είναι αδύνατο να ελεγχθεί, να επεκταθεί ή να τεκμηριωθεί.

Τρίτο παράδειγμα είναι μια τεχνολογική στοίβα όπου η Python χρησιμοποιείται για το backend, η Node.js για μια μικρουπηρεσία, η C# για τον desktop πελάτη και η Java για την εφαρμογή Android, ενώ όλη η επιχειρηματική λογική είναι διάσπαρτη μεταξύ τους χωρίς σαφή κατανομή ευθυνών.

javascript
// frankenstein — μικτά στυλ και τεχνολογίες
// callbacks, Promises και async/await συνδυασμένα

// callbacks
db.query("SELECT * FROM users", function(err, rows) {
  if (err) handleError(err);
  // Promise μέσα σε callback
  fetch("/api/data").then(function(data) {
    // async/await μέσα σε then
    (async () => {
      const result = await processData(data);
      sendResponse(result);
    })();
  });
});

// καθαρός κώδικας — ενοποιημένο στυλ async/await
async function getUserData(userId) {
  const user = await db.query("SELECT * FROM users WHERE id = ?", [userId]);
  const data = await fetch("/api/data/" + userId);
  return await processData(user, data);
}

Frankenstein σε επίπεδο δεδομένων

Μία βάση δεδομένων χρησιμοποιείται ταυτόχρονα ως SQL σχεσιακή (με κανονικοποίηση) και ως NoSQL προσανατολισμένη σε έγγραφα (με στήλες JSON). Μέρος των ερωτημάτων γίνεται μέσω ORM, μέρος μέσω αποθηκευμένων διαδικασιών, μέρος μέσω άμεσων SQL από τον κώδικα. Το σχήμα της βάσης δεν είναι τεκμηριωμένο, οι μεταναστεύσεις συγκρούονται.

Συνέπειες του κώδικα Frankenstein

Η πολυπλοκότητα ενσωμάτωσης είναι η πρώτη συνέπεια. Ένας νέος προγραμματιστής πρέπει να γνωρίζει 5 γλώσσες, 3 frameworks, 2 αρχιτεκτονικά στυλ για να καταλάβει πώς λειτουργεί το σύστημα. Η ενσωμάτωση διαρκεί από εβδομάδες έως μήνες. Σύμφωνα με το LinkedIn (2023), τα έργα με τεχνολογικό εκλεκτικισμό χάνουν νέους υπαλλήλους 2 φορές πιο συχνά.

Η απρόβλεπτη συμπεριφορά είναι η δεύτερη συνέπεια. Μια αλλαγή σε μια μικρουπηρεσία Python μπορεί απροσδόκητα να σπάσει ένα module Java επειδή χρησιμοποιούν κοινή βάση δεδομένων χωρίς σαφείς συμβάσεις. Η αποσφαλμάτωση τέτοιων προβλημάτων απαιτεί ταυτόχρονη γνώση όλων των τεχνολογιών στη στοίβα.

Η ασφάλεια είναι η τρίτη συνέπεια. Κάθε τεχνολογία στη στοίβα απαιτεί τη δική της διαμόρφωση ασφάλειας, τα δικά της patches, τη δική της παρακολούθηση. Η διατήρηση της ασφάλειας σε αποδεκτό επίπεδο για 5–6 ετερογενείς τεχνολογίες είναι πρακτικά αδύνατη. Μία από αυτές αναπόφευκτα θα αποδειχθεί ευάλωτη.

Τεχνικό χρέος του Frankenstein

Το SonarQube μπορεί να μετρήσει τεχνικό χρέος, αλλά δεν μπορεί να μετρήσει το “αρχιτεκτονικό χρέος” — την ασυμβατότητα των στοιχείων. Αυτό το χρέος δεν εμφανίζεται στις προειδοποιήσεις linter, αλλά στην αδυναμία προσθήκης μιας νέας λειτουργίας χωρίς αλλαγή τριών διαφορετικών modules γραμμένων σε διαφορετικές τεχνολογίες.

Πώς να αποφύγετε τη δημιουργία ενός τέρατος

Το πρώτο και σημαντικότερο βήμα είναι ο διορισμός ενός αρχιτέκτονα ή tech lead υπεύθυνου για την ακεραιότητα της τεχνολογικής στοίβας. Αυτό το άτομο έχει δικαίωμα βέτο στην εισαγωγή νέων τεχνολογιών χωρίς αρχιτεκτονική αναθεώρηση. Όχι δημοκρατία, αλλά υπεύθυνη ατομική απόφαση για τις βασικές τεχνολογίες.

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

Το τρίτο — καθιέρωση της αρχής “μία εργασία — ένα εργαλείο”. Για αιτήματα HTTP — ένας πελάτης. Για ORM — μία βιβλιοθήκη. Για καταγραφή — ένα framework. Εξαιρέσεις επιτρέπονται μόνο μέσω ADR με αιτιολόγηση. Αν υπάρχει ήδη Axios στο έργο — μην προσθέτετε fetch, αν υπάρχει SLF4J — μην γράφετε μέσω System.out.

  • Αρχιτέκτονας με δικαίωμα βέτο σε νέες τεχνολογίες
  • Architecture Decision Records για κάθε σημαντική επιλογή
  • Ενιαία στοίβα για κάθε εργασία — ένας HTTP πελάτης, ένα ORM
  • RFC για μεγάλες αλλαγές με συζήτηση της ομάδας
  • Τεχνολογικό ραντάρ για παρακολούθηση του τι μπορεί να εισαχθεί

Πολιτική πειραματικών τεχνολογιών

Τα πειράματα επιτρέπονται, αλλά σε απομονωμένο περιβάλλον. Ορίστε ένα module ή υπηρεσία που μπορεί να ξαναγραφεί με νέα τεχνολογία χωρίς επίδραση στο υπόλοιπο σύστημα. Αν το πείραμα πετύχει — τυποποιήστε το μέσω ADR. Αν όχι — αφαιρέστε το χωρίς συνέπειες.

Πώς να αναδομήσετε έναν υπάρχοντα Frankenstein

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

Η τυποποίηση είναι το δεύτερο βήμα. Επιλέξτε ένα εργαλείο για κάθε εργασία. Για παράδειγμα: μόνο Hibernate για ORM, μόνο SLF4J + Logback για καταγραφή, μόνο REST για API. Τεκμηριώστε το πρότυπο σε ADR. Ξεκινήστε την αντικατάσταση από τα modules όπου ο εκλεκτικισμός προκαλεί τα περισσότερα προβλήματα.

Η στρατηγική Parallel Run είναι το τρίτο βήμα. Τα παλιά και νέα εργαλεία λειτουργούν παράλληλα έως ότου το νέο αποδείξει την αξιοπιστία του. Για παράδειγμα, ο παλιός HTTP πελάτης και ο νέος λειτουργούν ταυτόχρονα, αλλά ο νέος μόνο για μέρος των αιτημάτων. Μετά από περίοδο σταθεροποίησης, ο παλιός αφαιρείται.

java
// frankenstein — τρεις HTTP προσεγγίσεις σε ένα έργο
// Module A: OkHttp
OkHttpClient client = new OkHttpClient().newCall(request);

// Module B: RestTemplate (Spring)
restTemplate.getForObject(url, String.class);

// Module C: java.net.HttpURLConnection
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();

// ενοποιημένη προσέγγιση: RestTemplate για sync, WebClient για reactive
@Autowired
private RestTemplate restTemplate;

public String callApi(String url) {
    return restTemplate.getForObject(url, String.class);
}

Ο ρόλος του τεχνικού ηγέτη στην πρόληψη

Ο τεχνικός ηγέτης είναι το κύριο εργαλείο στην καταπολέμηση του Frankenstein. Όχι διευθυντής, όχι αρχιτέκτονας σε πύργο από ελεφαντόδοντο, αλλά ένας ενεργός προγραμματιστής που γράφει κώδικα, κάνει ανασκόπηση PR και λαμβάνει αρχιτεκτονικές αποφάσεις. Χωρίς ένα τέτοιο άτομο, το έργο αναπόφευκτα ολισθαίνει στον τεχνολογικό εκλεκτικισμό.

Το RFC (Request for Comments) είναι μια διαδικασία δανεισμένη από τις κοινότητες Ανοιχτού Λογισμικού. Πριν από την εισαγωγή οποιασδήποτε σημαντικής τεχνολογίας, ο συγγραφέας γράφει ένα RFC: πρόβλημα, προτεινόμενη λύση, εναλλακτικές, σχέδιο εφαρμογής. Η ομάδα συζητά, ψηφίζει, αποδέχεται ή απορρίπτει. Το RFC δημιουργεί διαφάνεια και αποτρέπει “σιωπηλές” αρχιτεκτονικές αποφάσεις.

Το τεχνολογικό ραντάρ (Technology Radar από την ThoughtWorks) είναι ένα εργαλείο κατηγοριοποίησης τεχνολογιών: Adopt, Trial, Assess, Hold. Η ομάδα αναθεωρεί τακτικά το ραντάρ και ενημερώνει τις καταστάσεις. Αυτό βοηθά να διακρίνουμε το “μοδάτο” από το “χρήσιμο” και να αποφεύγουμε την εισαγωγή μη δοκιμασμένων τεχνολογιών σε κρίσιμο κώδικα.

Η αρχή της συνέπειας

Η σημαντικότερη ποιότητα της αρχιτεκτονικής είναι η συνέπεια (consistency). Ακόμα και ένα όχι το καλύτερο εργαλείο που χρησιμοποιείται σε ολόκληρο το έργο είναι καλύτερο από το καλύτερο εργαλείο που χρησιμοποιείται μόνο σε ένα module. Η συνέπεια μειώνει το γνωστικό φορτίο, απλοποιεί την ενσωμάτωση και κάνει τον κώδικα προβλέψιμο.

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

Πώς διαφέρει το Frankenstein από το polyglot persistence;

Το polyglot persistence είναι η συνειδητή χρήση διαφορετικών βάσεων δεδομένων για διαφορετικές εργασίες (PostgreSQL για συναλλαγές, Redis για προσωρινή μνήμη, Elasticsearch για αναζήτηση). Το Frankenstein είναι χαοτική ανάμειξη χωρίς στρατηγική. Η διαφορά βρίσκεται στην ύπαρξη αρχιτεκτονικής απόφασης: το polyglot είναι ένα σχέδιο, το Frankenstein είναι η απουσία του.

Μπορεί μια αρχιτεκτονική μικρουπηρεσιών να μετατραπεί σε Frankenstein;

Ναι, και είναι συχνό πρόβλημα. Όταν κάθε μικρουπηρεσία χρησιμοποιεί τη δική της γλώσσα, βάση δεδομένων, πρωτόκολλο και προσέγγιση ανάπτυξης χωρίς κεντρικοποιημένα πρότυπα — προκύπτει ένας κατανεμημένος Frankenstein. Για τις μικρουπηρεσίες, σημαντικά είναι τα κοινά πρότυπα: ενιαίο πρωτόκολλο (REST/gRPC), ενιαίο μορφότυπο αρχείων καταγραφής, κεντρικοποιημένη παρατηρησιμότητα.

Πώς να πείσω την ομάδα να μην χρησιμοποιήσει μια νέα τεχνολογία;

Μην απαγορεύετε — καθοδηγείτε. Ζητήστε από τον συγγραφέα RFC: να περιγράψει γιατί η υπάρχουσα λύση δεν είναι κατάλληλη, ποιες εναλλακτικές εξετάστηκαν, πώς θα γίνει η μετεγκατάσταση. Συχνά κατά τη διαδικασία σύνταξης του RFC, ο προγραμματιστής καταλαβαίνει ότι η νέα τεχνολογία δεν χρειάζεται. Αν το RFC είναι πειστικό — εφαρμόστε το, αλλά με σχέδιο και περιορισμούς.

Πώς να αντιμετωπίσουμε τον Frankenstein σε ένα κληρονομημένο έργο;

Πρώτα καταγραφή, μετά τυποποίηση. Μην προσπαθήσετε να ξαναγράψετε τα πάντα ταυτόχρονα. Ορίστε ένα επίπεδο (π.χ. HTTP πελάτες ή καταγραφή), επιλέξτε ένα ενιαίο εργαλείο, γράψτε ADR και μεταφερθείτε σταδιακά. Η μέθοδος Strangler Fig — αντικαταστήστε τα παλιά στοιχεία ένα προς ένα χωρίς να σταματήσετε την εφαρμογή.

Πόσες τεχνολογίες είναι βέλτιστες για ένα έργο;

Όσο λιγότερες, τόσο καλύτερα. Ιδανικά — μία γλώσσα, ένα framework, μία βάση δεδομένων, ένας τρόπος καταγραφής. Ρεαλιστικά — 2–3 γλώσσες (με σαφή διαχωρισμό), 1–2 βάσεις δεδομένων, 1–2 frameworks. Κάθε επιπλέον τεχνολογία αυξάνει το γνωστικό φορτίο της ομάδας και το κόστος συντήρησης.

Σύνοψη

  • Frankenstein — ένα αντι-πρότυπο όπου το σύστημα είναι συναρμολογημένο από ετερογενή ασύμβατα στοιχεία
  • Κύριες αιτίες: απουσία αρχιτέκτονα, συγχώνευση έργων, ανεξέλεγκτα πειράματα
  • Συνέπειες — περίπλοκη ενσωμάτωση, απρόβλεπτη συμπεριφορά, προβλήματα ασφάλειας
  • ADR και RFC — βασικές διαδικασίες για την πρόληψη του αρχιτεκτονικού εκλεκτικισμού
  • Η αρχή “ένα εργαλείο ανά εργασία” — η βάση της πρόληψης
  • Η αναδόμηση ξεκινά με καταγραφή και τυποποίηση της τεχνολογικής στοίβας
  • Η συνέπεια της αρχιτεκτονικής είναι σημαντικότερη από το “καλύτερο εργαλείο” για μία υπο-εργασία

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

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

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

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