Φιλοσοφίες σχεδιασμού

Αυτό το άρθρο εξηγεί μερικές από τις θεμελιώδεις φιλοσοφίες των developers του Django οι οποίοι ακολουθώντας τες, έχτισαν το framework. Ο στόχος τους είναι να εξηγήσει το παρελθόν και να οδηγήσει το μέλλον.

Γενικά

Ανεξαρτητοποίηση μεταξύ οντοτήτων (loose coupling)

Ένας θεμελιώδης στόχος των πολλαπλών επιπέδων του Django (models, views, templates κλπ) είναι: ανεξαρτητοποίηση των οντοτήτων και η σταθερή συνοχή του καθενός. Τα διάφορα επίπεδα του framework δεν θα πρέπει να «γνωρίζουν» το ένα το άλλο εκτός και αν κριθεί απολύτως αναγκαίο.

Για παράδειγμα, το σύστημα των templates δε ξέρει απολύτως τίποτα σχετικά με τα Web requests, το επίπεδο της βάσης δεδομένων δε ξέρει τίποτα για την εμφάνιση των δεδομένων και, τέλος, δεν ενδιαφέρει το σύστημα των views ποιο σύστημα template χρησιμοποιεί ο προγραμματιστής.

Παρόλο που, για λόγους ευκολίας, το Django περιέχει όλα τα επίπεδα προεγκατεστημένα, καθένα από αυτά είναι ανεξάρτητο του άλλου, όπου αυτό είναι δυνατόν.

Λιγότερος κώδικας

Οι Django εφαρμογές (apps) θα πρέπει να χρησιμοποιούν όσο το δυνατόν λιγότερο κώδικα. Με άλλα λόγια θα πρέπει να στερούνται στερεότυπους κώδικες. Το Django θα πρέπει να εκμεταλλευτεί πλήρως τις δυναμικές ικανότητες της Python όπως είναι η ενδοσκόπηση (introspection).

Γρήγορη ανάπτυξη

Ο στόχος ενός Web framework, στον 21ο αιώνα, είναι να κάνει τις ανιαρές πτυχές του Web development γρήγορες. Το Django κάνει τη διαδικασία του Web development εξαιρετικά γρήγορη.

Μην επαναλαμβάνεστε (Don’t repeat yourself, DRY)

Κάθε ξεχωριστή έννοια ή/και κάποιο κομμάτι δεδομένων θα πρέπει να βρίσκεται σε ένα και μόνο ένα σημείο. Ο πλεονασμός είναι κακός. Η ομαλοποίηση είναι καλή.

Το framework, μέσα σε λογικά πλαίσια, θα πρέπει να εξάγει όσο το δυνατόν περισσότερα από όσο το δυνατόν λιγότερα.

Το να λες κάτι ρητά είναι καλύτερο απ’ το να το υπονοείς (Explicit is better than implicit)

Αυτό είναι η θεμελιώδης αρχή της Python η οποία περιλαμβάνεται στο PEP 20 και σημαίνει ότι το Django δεν θα πρέπει να κάνει πολλά «μαγικά.» Τα μαγικά δεν πρέπει να υπάρχουν εκτός και αν υπάρχει ένας πολύ καλός λόγος. Τα μαγικά αξίζει να γίνουν αν προσφέρουν τεράστια ευκολία η οποία είναι ανέφικτη με άλλους τρόπους και η υλοποίηση τους έχει γίνει με τέτοιο τρόπο που να μην μπερδεύει τους προγραμματιστές οι οποίοι προσπαθούν να καταλάβουν πως να χρησιμοποιήσουν το feature.

Συνοχή

Το framework θα πρέπει να έχει συνοχή σε όλα τα επίπεδα. Η έννοια της συνοχής εφαρμόζεται στα πάντα, από τα χαμηλού επιπέδου (το στυλ του Python κώδικα που χρησιμοποιείται) μέχρι τα υψηλού επιπέδου (η «εμπειρία» πάνω στο Django).

Μοντέλα

Το να λες κάτι ρητά είναι καλύτερο απ’ το να το υπονοείς (Explicit is better than implicit)

Τα πεδία (fields) δεν θα πρέπει να υποθέτουν κάποιες συμπεριφορές βασιζόμενα μόνο και μόνο στο όνομα του πεδίου. Αυτό απαιτεί πολλή γνώση από το σύστημα και είναι ευάλωτο σε λάθη. Αντιθέτως, οι συμπεριφορές θα πρέπει να βασίζονται στα keyword arguments και, σε μερικές περιπτώσεις, στον τύπο του πεδίου.

Περίληψη όλων των σχετικών με το μοντέλο πληροφορίες

Τα μοντέλα θα πρέπει να ενσωματώσουν όλες τις έννοιες που αφορούν ένα «object,» σύμφωνα με το άρθρο Active Record του Martin Fowler σχετικά με πρακτικές σχεδιασμού.

Να λοιπόν γιατί τα δεδομένα που αναπαριστώνται από το μοντέλο και οι πληροφορίες σχετικά με αυτά (το όνομα όπως θα εμφανίζεται στον χρήστη, επιλογές όπως προεπιλεγμένη ταξινόμηση κλπ) ορίζονται μέσα στην κλάση του μοντέλου. Όλη η πληροφορία που χρειάζεται για να κατανοηθεί ένα μοντέλο θα πρέπει να αποθηκεύεται μέσα στο μοντέλο.

Το API της βάσης δεδομένων

Οι βασικοί στόχοι του API της βάσης δεδομένων είναι:

Αποδοτικότητα της SQL

Το framework θα πρέπει να εκτελεί όσο το δυνατόν λιγότερες φορές τις SQL εντολές και να τις βελτιστοποιεί στο εσωτερικό του.

Να γιατί οι developers χρειάζεται να καλούν την μέθοδο save() ρητώς, παρά να επαφίενται στο framework να αποθηκεύει σιωπηλά τα objects στο παρασκήνιο.

Επίσης, αυτός είναι ο λόγος της ύπαρξης της μεθόδου select_related() του QuerySet. Είναι ένας προαιρετικός αρωγός απόδοσης για συνηθισμένες περιπτώσεις του τύπου «επέλεξε κάθε συσχετισμένο object».

Λακωνική, ισχυρή σύνταξη

Το API της βάσης δεδομένων θα πρέπει να επιτρέπει πλούσια και εκφραστικά statements με όσο το δυνατόν λιγότερη σύνταξη. Δεν θα πρέπει να βασίζεται στην εισαγωγή (import) άλλων modules ή βοηθητικών objects.

Οι εντολές “JOIN” της SQL θα πρέπει να γίνονται αυτομάτως, στο παρασκήνιο, όταν είναι απαραίτητο.

Κάθε object θα πρέπει να έχει πρόσβαση σε κάθε συσχετισμένο object, μέσα σε όλο το σύστημα. Αυτού του είδους η πρόσβαση θα πρέπει να δουλεύει και ανάποδα.

Επιλογή να μπορεί γράφεται SQL εύκολα, όποτε χρειάζεται

Το API της βάσης δεδομένων θα πρέπει να συνειδητοποιήσει ότι είναι μια συντόμευση και όχι απαραίτητα ένα API που τα κάνει όλα. Το framework θα πρέπει να κάνει εύκολη τη γραφή προσαρμοσμένων SQL εντολών – είτε ολόκληρων είτε προσαρμοσμένων WHERE εντολών μόνο, ως παραμέτρους στις κλήσεις του API.

Σχεδιασμός URL

Ανεξαρτητοποίηση μεταξύ οντοτήτων (loose coupling)

Τα URLs μέσα σε μια Django εφαρμογή (app) δεν θα πρέπει να εμπλέκονται με τον Python κώδικα που είναι γραμμένος. Η σύνδεση των URLs σε ονόματα Python συναρτήσεων είναι Κακό Και Άσχημο Πράγμα.

Σύμφωνα με τα ανωτέρω, το σύστημα URL του Django θα πρέπει να επιτρέπει τα URLs της ίδιας εφαρμογής να είναι διαφορετικά ανάμεσα σε διαφορετικά πλαίσια (contexts). Για παράδειγμα, ένα site μπορεί να φιλοξενήσει την εφαρμογή “stories” στη διεύθυνση /stories/ ενώ ένα άλλο να φιλοξενήσει την ίδια εφαρμογή στη διεύθυνση /news/.

Απεριόριστη ευελιξία

Τα URLs θα πρέπει να είναι όσο το δυνατόν πιο ευέλικτα. Κάθε νοητή σχεδίαση ενός URL θα πρέπει να επιτρέπεται.

Ενθάρρυνση καλών πρακτικών

Το framework θα πρέπει να κάνει εύκολη (αν όχι ευκολότερη), για τον developer, τη σχεδίαση όμορφων παρά άσχημων URLs.

Οι καταλήξεις αρχείων στα URLs ιστοσελίδων πρέπει να αποφεύγονται.

Τα κόμματα, τύπου Vignette, στα URLs χρήζουν αυστηρής τιμωρίας.

Οριστικά URLs

Σε τεχνικό επίπεδο, το foo.com/bar και foo.com/bar/ είναι δύο διαφορετικά URLs και τα ρομπότ των μηχανών αναζήτησης (όπως επίσης και μερικά εργαλεία ανάλυσης της κίνησης στο Web) θα τα μεταχειριστούν ως διαφορετικές σελίδες. Το Django θα πρέπει να καταβάλλει προσπάθεια προκειμένου να «ομαλοποιήσει» τα URLs ούτως ώστε τα ρομπότ των μηχανών αναζήτησης να μην μπερδευτούν.

Αυτό είναι ο λόγος πίσω από τη ρύθμιση APPEND_SLASH.

Σύστημα template

Διαχωρισμός μεταξύ λογικής και παρουσίασης

Βλέπουμε το σύστημα του template ως ένα εργαλείο που ελέγχει την παρουσίαση και ότι έχει να κάνει με την λογική πίσω από την παρουσίαση. Μόνο αυτό. Το σύστημα template δεν θα πρέπει να πάει παραπέρα από αυτό τον στόχο.

Αποθάρρυνση του πλεονασμού

Η πλειονότητα των δυναμικών ιστοσελίδων χρησιμοποιεί ένα είδος κοινού σχεδιασμού ολόκληρου του site – κοινό header, footer, μπάρα πλοήγησης κλπ. Το σύστημα template του Django θα πρέπει να κάνει εύκολη την αποθήκευση αυτών των στοιχείων σε ένα μέρος, εξαλείφοντας τη χρήση επαναλαμβανόμενου κώδικα.

Αυτή είναι η φιλοσοφία πίσω από την κληρονομικότητα του template.

Μη συσχέτιση με την HTML

Το σύστημα template δεν θα πρέπει να σχεδιαστεί για να παράγει μόνο HTML. Θα πρέπει να είναι εξίσου καλό στο να παράγει και άλλες μορφές που βασίζονται στο κείμενο ή απλώς σκέτο κείμενο.

Η XML δεν θα πρέπει να χρησιμοποιείται σε γλώσσες template

Η χρήση μιας XML μηχανής για να αναλύσει τα templates εισάγει έναν εντελώς νέο κόσμο από ανθρώπινα λάθη κατά την επεξεργασία τους. Παράλληλα προσθέτει ένα απαράδεκτο overhead κατά την επεξεργασία του template.

Υποθέτει τη συμμετοχή του designer

Το σύστημα template δεν θα πρέπει να σχεδιαστεί με τρόπο που τα templates να εμφανίζονται, απαραιτήτως, ως WYSIWYG επεξεργαστές, όπως το Dreamweaver. Αυτό αποτελεί σημαντικό περιορισμό και δεν επιτρέπει στη σύνταξη να είναι τόσο όμορφη όσο θα έπρεπε να είναι. Το Django υποθέτει ότι οι συντάκτες των templates είναι εξοικειωμένοι με την επεξεργασία της HTML.

Διαχείριση των κενών χαρακτήρων με τον προφανή τρόπο

Το σύστημα template δεν θα πρέπει να κάνει μαγικά πράγματα με τους κενούς χαρακτήρες (whitespace). Αν ένα template περιέχει κενά, τότε το σύστημα θα τα διαχειριστεί ως κείμενο και θα τα εμφανίσει. Κάθε κενό που δεν βρίσκεται μέσα σε κάποιο template tag θα εμφανίζεται.

Όχι στην εφεύρεση μια γλώσσας προγραμματισμού

Ο στόχος δεν είναι να εφεύρουμε μια γλώσσα προγραμματισμού. Ο στόχος είναι να προσφέρουμε ένα είδος προγραμματιστικής λειτουργίας στο template όπως ο βρόγχος επανάληψης και οι δομές ελέγχου, κάτι το οποίο είναι ζωτικής σημασίας όταν σχεδιάζουμε ένα template. H Γλώσσα Template του Django (DTL) αποφεύγει τις προχωρημένες λογικές.

Το σύστημα template του Django αναγνωρίζει ότι τα templates γράφονται συχνά από designers, όχι από προγραμματιστές και, επομένως, δεν θα πρέπει να απαιτεί από τον συντάκτη να έχει γνώσεις Python.

Ασφάλεια και προστασία

Το σύστημα template, εξ ορισμού, θα πρέπει να μην επιτρέπει την εισαγωγή κακόβουλου κώδικα – όπως εντολές οι οποίες διαγράφουν δεδομένα από την βάση δεδομένων.

Αυτός είναι ένας άλλος λόγος που το σύστημα template δεν επιτρέπει την εισαγωγή Python κώδικα.

Επεκτασιμότητα

Το σύστημα template θα πρέπει να παρέχει στους προχωρημένους συντάκτες template τη δυνατότητα επέκτασης και περαιτέρω παραμετροποίησης του.

Αυτή είναι η φιλοσοφία πίσω από τα παραμετροποιήσιμα φίλτρα και template tags.

Views

Απλότητα

Η σύνταξη ενός view θα πρέπει να είναι τόσο απλή όσο μιας Python συνάρτησης. Οι developers δεν θα πρέπει να αρχικοποιούν (instantiate) μια κλάση όταν μπορούν να χρησιμοποιήσουν, απλώς, μια συνάρτηση.

Χρήση των request objects

Τα views θα πρέπει να έχουν πρόσβαση σε ένα request object – ένα object, δηλαδή, που αποθηκεύει metadata σχετικά με το τρέχον request (αυτό που έκανε ο χρήστης). Το object θα πρέπει να περαστεί απ’ ευθείας στη συνάρτηση view, παρά η συνάρτηση view να έχει πρόσβαση στα request data μέσω μιας global μεταβλητής. Αυτό το καθιστά ελαφρύ, καθαρό και εύκολο να ελεγχθούν τα views περνώντας ως όρισμα «ψεύτικα» request objects.

Ανεξαρτητοποίηση μεταξύ οντοτήτων (loose coupling)

Ένα view δεν θα πρέπει να ενδιαφέρεται για το σύστημα template που χρησιμοποιεί ο developer – ή ακόμη και για το αν χρησιμοποιείται κάποιο.

Διαφοροποίηση μεταξύ GET και POST

Το GET και το POST είναι ξεχωριστά. Οι developers θα πρέπει να δηλώνουν ρητώς ποια μέθοδο θα χρησιμοποιούν. Το framework θα πρέπει να κάνει εύκολο το διαχωρισμό μεταξύ των GET και POST δεδομένων.

Cache Framework

Οι βασικοί στόχοι του cache framework του Django είναι:

Λιγότερος κώδικας

Μια cache θα πρέπει να είναι όσο γίνεται πιο γρήγορη. Επομένως, όλος ο κώδικας του framework που περιβάλλει την cache backend θα πρέπει να διατηρείται σε χαμηλά επίπεδα, ειδικά για περιπτώσεις που ζητάμε κάτι από την cache (get()).

Συνοχή

Το API της cache θα πρέπει να παρέχει ένα interface με συνοχή ανάμεσα σε διαφορετικά cache backends.

Επεκτασιμότητα

Το API της cache θα πρέπει να είναι επεκτάσιμο σε επίπεδο εφαρμογής ανάλογα με τις απαιτήσεις του developer (για παράδειγμα, δείτε στην Cache key transformation).

Back to Top