AOP εναντίον λειτουργιών

Ο προγραμματισμός προσανατολισμού (AOP) είναι αρκετά δημοφιλής. Το κίνητρο για αυτό εξηγείται καλά στο αντίστοιχο άρθρο της Βικιπαίδειας.

Το AOP είναι ένα εξαιρετικό εργαλείο για πραγματικά παγκόσμιες έννοιες όπως η καταγραφή που δεν επηρεάζουν άμεσα τη λογική του κώδικα. Ωστόσο, τα προβλήματα με το AOP εμφανίζονται όταν χρησιμοποιούνται για περισσότερα πράγματα που σχετίζονται με επιχειρήσεις, όπως η εξουσιοδότηση. Αυτές οι πτυχές της εφαρμογής πρέπει να είναι σαφώς ορατές στον σχετικό κώδικα, έτσι ώστε ο προγραμματιστής να μπορεί να δει αμέσως εάν εφαρμόζονται σωστά κατά την ανάγνωση του αντίστοιχου πηγαίου κώδικα. Τα πλαίσια που βασίζονται σε AOP τυπικά λύνουν γι 'αυτό χρησιμοποιώντας σχολιασμούς μεθόδων:

@RequireRole (Role.Admin) // εμφανής όψη
fun updateUserPermissions (...) {
    // λογική εδώ
}}

Ωστόσο, από την άποψη της αναγνωσιμότητας, δεν διαφέρει πολύ από μια λειτουργική προσέγγιση στο ίδιο πρόβλημα χρησιμοποιώντας τη συνάρτηση requRole αντί για το σχολιασμό @RequireRole:

fun updateUserPermissions (...) {
    requireRole (Role.Admin) // ρίχνει το SecurityException
    // λογική εδώ
}}

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

Το ίδιο ισχύει και για άλλες πτυχές όπως οι συναλλαγές. Δυστυχώς, είναι δυσκίνητη και δυσάρεστη η λειτουργική εκπροσώπηση πιο περίπλοκων εννοιών στην Java, γεγονός που δημιουργεί τεχνητή δημοτικότητα για τα πλαίσια AOP στο οικοσύστημα Java.

Δεν συμβαίνει όμως με τον Kotlin. Στο Kotlin, αντί της προσέγγισης της Java με τις συναλλαγές με AOP και σχολιασμούς όπως αυτό:

@Transactional
fun updateUserPermissions (...) {
    // λογική εδώ
}}

Είναι εξίσου ευανάγνωστο και καθαρό, όταν ξαναγραφεί με λειτουργικό τρόπο:

fun updateUserPermissions (...) = συναλλακτική {
    // λογική εδώ
}}

Το πλεονέκτημα αυτής της λειτουργικής προσέγγισης είναι ότι μπορείτε πάντα να Ctrl / Cmd + Κάντε κλικ στη δήλωση της συναλλακτικής λειτουργίας στο IDE και αμέσως να δείτε τι ακριβώς κάνει, κάτι που συνήθως δεν είναι δυνατό με κανένα από τα κοινά χρησιμοποιούμενα πλαίσια AOP. Ακόμη και όταν η πλοήγηση στον πηγαίο κώδικα της οθόνης παρέχεται από μια προσθήκη IDE, η αποκρυπτογράφηση της λογικής της απαιτεί γνώση ενός ξεχωριστού πλούσιου API ή / και συμβάσεων.

Δυστυχώς, αυτή η λειτουργική αντικατάσταση για το AOP που βασίζεται σε σχολιασμούς στο Kotlin δεν κλιμακώνει αμέσως στην περίπτωση που εφαρμόζονται πολλαπλές πτυχές για την ίδια λειτουργία με τα σγουράκια και η εσοχή αρχίζουν να συσσωρεύονται:

fun updateUserPermissions (...) = καταγεγραμμένο {
    συναλλακτική {
        // λογική εδώ
    }}
}}

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

fun updateUserPermissions (...) = loggedTransactional {
    // λογική εδώ
}}

Ένα άλλο μειονέκτημα της λειτουργικής προσέγγισης είναι ότι οι πτυχές όπως η καταγραφή χρειάζονται πρόσβαση στις παραμέτρους μεθόδου. Είναι συνήθως άμεσα διαθέσιμα σε παραδοσιακά πλαίσια AOP μέσω ειδικών API, αλλά οι λειτουργίες του Stock Kotlin δεν μπορούν εύκολα να έχουν πρόσβαση σε αυτά. Έτσι, για να αντιπροσωπεύσουμε πραγματικά την πτυχή της καταγραφής της πραγματικής ζωής με καθαρά λειτουργικό τρόπο, πρέπει κανείς να γράψει ένα σημαντικό ποσό κωδικού λέβητα:

διασκέδαση updateUserPermissions (παραμέτρους: Params) =
    καταγεγραμμένο ("updateUserPermissions ($ params)") {
        // λογική εδώ
    }}

Αυτό το σχόλιο εξακολουθεί να καθιστά το AOP εργαλείο επιλογής για την καταγραφή, όταν πραγματικά χρειάζεται να το έχετε παγκοσμίως και σταθερά στην αίτησή σας, αλλά πιστεύω ότι η χρήση του AOP για πτυχές όπως η εξουσιοδότηση και οι συναλλαγές είναι κατάχρηση, δεδομένης της πλούσιας λειτουργικής αφαίρεσης που είναι διαθέσιμη στο Kotlin . Οι λειτουργίες αντιμετωπίζουν αυτές τις πτυχές καλύτερα και καθαρότερα.

Για να ολοκληρώσω θα έλεγα ότι περαιτέρω βελτιώσεις στις λειτουργικές αφαίρεσεις για να δώσουν μια ακόμη καλύτερη αντικατάσταση για AOP θα μπορούσε να είναι ένας πολλά υποσχόμενος φορέας της μελλοντικής εξέλιξης για τη γλώσσα Kotlin. Τα πλαίσια AOP που βασίζονται στην Java είναι συνήθως JVM-συγκεκριμένα και θεωρούνται ως κάποια αδιαφανή μαγεία, ενώ οι λειτουργικές αφαιρέσεις Kotlin είναι πραγματικά cross-platform και είναι διαφανείς για τον χρήστη.