Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

Ζητείται το κατάλληλο pattern

Îåêßíçóå áðü ôï ìÝëïò KelMan. Τελευταία δημοσίευση από το μέλος Παναγιώτης Καναβός στις 29-01-2010, 11:51. Υπάρχουν 1 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  29-01-2010, 10:16 56777

    Ζητείται το κατάλληλο pattern

    Λοιπόν, η παρούσα κατάσταση:

    Έχω μια κλάση, ας την πούμε Manager που περιέχει ένα collection από objects. Ο Manager έχει ένα method το οποίο κάνει ένα operation για κάθε ένα object του collection, δηλαδή δεν αλλάζει το ίδιο το object, απλά χρησιμοποιεί το state του.

    Σε κάποιο σημείο του operation, τρέχει ένα function πάνω στο object το οποίο function δεν το γνωρίζει ο Manager, γνωρίζει μόνο το αντίστοιχο delegate του function που θα πρέπει να χρησιμοποιήσει. Όταν φτιάχνω τον Manager, του περνάω ως παράμετρο το function κι έτσι όλα τρέχουν μια χαρά.

    Το πρόβλημα:

    Παρουσιάστηκε η ανάγκη το collection να περιέχει κι ένα δεύτερο είδος από objects, για τα οποία (γιατί να είναι εύκολα τα πράγματα;) απαιτείται διαφορετικό function μέσα στο operation του Manager.

    Η ερώτηση:

    Ψάχνω κάποιο κατάλληλο pattern ώστε να υλοποιήσω το παραπάνω requirement. Σκέφτομαι ότι αν είχα covariance ίσως τα πράγματα να ήταν πιο απλά φτάχνοντας ένα generic τύπο και "μετακομίζοντας" το delegate μέσα στον τύπο. Φυσικά, θέλω να αποφύγω να βάλω μέσα στο operation του Manager λογική του τύπου "αν το object είναι τέτοιο, κάνε αυτό, αν είναι τέτοιο, κάνε εκείνο, κλπ" καθώς μπορεί να εμφανιστεί αύριο η ανάγκη να υποστηριχθεί κι ένα τρίτο είδος από objects. Έχει κανείς καμιά ιδέα;

     

     

     


    Vir prudens non contra ventum mingit
  •  29-01-2010, 11:51 56781 σε απάντηση της 56777

    Απ: Ζητείται το κατάλληλο pattern

    Αυτό που ψάχνεις είναι το Visitor pattern και οι παραλλαγές του. Περιγράφει ένα τρόπο να εκτελέσει κάποιο function σε κάθε μέλος ενός iteration. Οι στόχοι του είναι: να "μαζέψει" τη λογική του iteration σε ένα σημείο, να παρέχει ένα ξεχωριστό function για κάθε διαφορετικό τύπο αντικειμένου, χωρίς να σε αναγκάσει όμως να προσθέτεις ένα καινούριο function κάθε φορά που προσθέτεις ένα νέο τύπο και τέλος να παρέχει ένα κοινό state για όλη τη διάρκεια του iteration.

    Η τυπική μορφή του περιγράφεται στο Gang of Four και περιλαμβάνει μία κλάση Visitor η οποία περιέχει τη λογική του iteration (π.χ. για απλή λίστα, δέντρο, linked list, με συγκεκριμένη σειρά, iteration με φίλτρα, ο,τιδήποτε). Κάθε αντικείμενο στη λίστα θα πρέπει να υλοποιεί ένα interface το με ένα function AcceptVisitor. Για κάθε αντικείμενο στη λίστα ο Visitor καλεί την AcceptVisitor στο αντικείμενο περνώντας τον εαυτό του ως παράμετρο. Όλο αυτό το "πέρα-δώθε" γίνεται για να μη γεμίσει ο Visitor με διαφορετικά Visit functions για κάθε νέο τύπο αντικειμένου.

    Η αρχική μορφή είναι λίγο περίεργη λόγω του πέρα-δώθε και της ανάγκης παρέμβασης στα αντικείμενα. Γι αυτό το λόγο έχουν βγει αρκετές παραλλαγές του Visitor οι οποίες απλοποιούν την κατάσταση. Στο .NET μάλιστα μπορείς να χρησιμοποιήσεις μηχανισμούς που ήδη υπάρχουν για να πετύχεις το ίδιο αποτέλεσμα:

    • Καταρχήν, μπορείς να χρησιμοποιήσεις iterators για να υλοποιήσεις τη λογική του iteration. Με τον τρόπο αυτό το iteration μετατρέπεται σε ένα απλό foreach
    • Mπορείς να χρησιμοποιήσεις delegates ή ακομα καλύτερα, extension methods για να υλοποιήσεις την AcceptVisitor χωρίς να παρέμβεις στα αντικείμενα.
    • Mπορείς να χρησιμοποιήσεις lambdas για να ορίσεις τον κώδικα που θα εκτελεστεί ακριβώς στο σημείο που γίνεται το iteration. Έτσι μπορείς να εκτελέσεις διαφορετικά functions ακόμα και για τον ίδιο τύπο αντικειμένου.
    • Τέλος, μπορείς να χρησιμοποιήσεις LINQ για να τα συνδυάσεις όλα αυτά. Η Aggregate μάλιστα κάνει λίγο-πολύ την ίδια δουλειά που κάνει ο Visitor - περνάει από κάθε αντικείμενο σε ένα collection, εφαρμόζει το ίδιο lambda κρατώντας state μέχρι το τέλος του iteration. Αν το fuction που καλείς μάλιστα είναι extension method μπορείς να εκτελείς διαφορετική μέθοδο ανά τύπο, χωρίς να παρέμβεις στα αντικείμενα του collection

    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems