<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="https://www.dotnetzone.gr:443/cs/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Design &amp; Architecture</title><link>https://www.dotnetzone.gr:443/cs/forums/16/ShowForum.aspx</link><description>Θέματα αρχιτεκτονικής και σχεδιασμού εφαρμογών (design patterns, object orientation, κ.α.)</description><dc:language>el</dc:language><generator>CommunityServer 2.1 SP3 (Build: 20423.1)</generator><item><title>Απ: Ζητείται το κατάλληλο pattern</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/56781.aspx</link><pubDate>Fri, 29 Jan 2010 19:51:58 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:56781</guid><dc:creator>Παναγιώτης Καναβός</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/56781.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=16&amp;PostID=56781</wfw:commentRss><description>&lt;P&gt;Αυτό που ψάχνεις είναι το Visitor pattern και οι παραλλαγές του. Περιγράφει ένα τρόπο να εκτελέσει κάποιο function σε κάθε μέλος ενός iteration. Οι στόχοι του είναι: να "μαζέψει" τη λογική του iteration σε ένα σημείο, να παρέχει ένα ξεχωριστό function για κάθε διαφορετικό τύπο αντικειμένου, χωρίς να σε αναγκάσει όμως να προσθέτεις ένα καινούριο function κάθε φορά που προσθέτεις ένα νέο τύπο και τέλος να παρέχει ένα κοινό state για όλη τη διάρκεια του iteration. &lt;/P&gt;
&lt;P&gt;Η τυπική μορφή του περιγράφεται στο Gang of Four και περιλαμβάνει μία κλάση Visitor η οποία περιέχει τη λογική του iteration (π.χ. για απλή λίστα, δέντρο, linked list, με συγκεκριμένη σειρά, iteration με φίλτρα, ο,τιδήποτε). Κάθε αντικείμενο στη λίστα θα πρέπει να υλοποιεί ένα interface το με ένα function AcceptVisitor. Για κάθε αντικείμενο στη λίστα ο Visitor καλεί την AcceptVisitor στο αντικείμενο περνώντας τον εαυτό του ως παράμετρο. Όλο αυτό το "πέρα-δώθε" γίνεται για να μη γεμίσει ο Visitor με διαφορετικά Visit functions για κάθε νέο τύπο αντικειμένου.&lt;/P&gt;
&lt;P&gt;Η αρχική μορφή είναι λίγο περίεργη λόγω του πέρα-δώθε και της ανάγκης παρέμβασης στα αντικείμενα. Γι αυτό το λόγο έχουν βγει αρκετές παραλλαγές του Visitor οι οποίες απλοποιούν την κατάσταση. Στο .NET μάλιστα μπορείς να χρησιμοποιήσεις μηχανισμούς που ήδη υπάρχουν για να πετύχεις το ίδιο αποτέλεσμα:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Καταρχήν, μπορείς να χρησιμοποιήσεις iterators για να υλοποιήσεις τη λογική του iteration. Με τον τρόπο αυτό το iteration μετατρέπεται σε ένα απλό foreach&lt;/LI&gt;
&lt;LI&gt;Mπορείς να χρησιμοποιήσεις delegates ή ακομα καλύτερα, extension methods για να υλοποιήσεις την AcceptVisitor χωρίς να παρέμβεις στα αντικείμενα. &lt;/LI&gt;
&lt;LI&gt;Mπορείς να χρησιμοποιήσεις lambdas για να ορίσεις τον κώδικα που θα εκτελεστεί ακριβώς στο σημείο που γίνεται το iteration. Έτσι μπορείς να εκτελέσεις διαφορετικά functions ακόμα και για τον ίδιο τύπο αντικειμένου.&lt;/LI&gt;
&lt;LI&gt;Τέλος, μπορείς να χρησιμοποιήσεις LINQ για να τα συνδυάσεις όλα αυτά. Η Aggregate μάλιστα κάνει λίγο-πολύ την ίδια δουλειά που κάνει ο Visitor - περνάει από κάθε αντικείμενο σε ένα collection, εφαρμόζει το ίδιο lambda κρατώντας state μέχρι το τέλος του iteration. Αν το fuction που καλείς μάλιστα είναι extension method μπορείς να εκτελείς διαφορετική μέθοδο ανά τύπο, χωρίς να παρέμβεις στα αντικείμενα του collection&lt;/LI&gt;&lt;/UL&gt;</description></item><item><title>Ζητείται το κατάλληλο pattern</title><link>https://www.dotnetzone.gr:443/cs/forums/thread/56777.aspx</link><pubDate>Fri, 29 Jan 2010 18:16:18 GMT</pubDate><guid isPermaLink="false">2622095e-976c-431a-859e-16783ec7ecd7:56777</guid><dc:creator>KelMan</dc:creator><slash:comments>0</slash:comments><comments>https://www.dotnetzone.gr:443/cs/forums/thread/56777.aspx</comments><wfw:commentRss>https://www.dotnetzone.gr:443/cs/forums/commentrss.aspx?SectionID=16&amp;PostID=56777</wfw:commentRss><description>&lt;P&gt;Λοιπόν, η παρούσα κατάσταση:&lt;/P&gt;
&lt;P&gt;Έχω μια κλάση, ας την πούμε Manager&amp;nbsp;που περιέχει ένα collection από objects. Ο Manager έχει ένα method το οποίο κάνει ένα operation για κάθε ένα object του collection, δηλαδή δεν αλλάζει το ίδιο το object, απλά χρησιμοποιεί το state του.&lt;/P&gt;
&lt;P&gt;Σε κάποιο σημείο του operation, τρέχει ένα&amp;nbsp;function&amp;nbsp;πάνω στο&amp;nbsp;object το οποίο function δεν το γνωρίζει ο Manager, γνωρίζει μόνο το αντίστοιχο delegate του function που θα πρέπει να χρησιμοποιήσει. Όταν φτιάχνω τον Manager, του περνάω ως παράμετρο το function κι έτσι όλα τρέχουν μια χαρά.&lt;/P&gt;
&lt;P&gt;Το πρόβλημα:&lt;/P&gt;
&lt;P&gt;Παρουσιάστηκε η ανάγκη το collection να περιέχει κι ένα δεύτερο είδος από objects, για τα οποία (γιατί να είναι εύκολα τα πράγματα;) απαιτείται διαφορετικό function μέσα στο operation του Manager. &lt;/P&gt;
&lt;P&gt;Η ερώτηση:&lt;/P&gt;
&lt;P&gt;Ψάχνω κάποιο κατάλληλο pattern ώστε να υλοποιήσω το παραπάνω requirement. Σκέφτομαι ότι αν είχα covariance ίσως τα πράγματα να ήταν πιο απλά φτάχνοντας ένα generic τύπο και&amp;nbsp;"μετακομίζοντας" το delegate μέσα στον τύπο. Φυσικά, θέλω να αποφύγω να βάλω μέσα στο operation του Manager λογική του τύπου "αν το object είναι τέτοιο, κάνε αυτό, αν είναι τέτοιο, κάνε εκείνο, κλπ" καθώς μπορεί να εμφανιστεί αύριο η ανάγκη να υποστηριχθεί κι ένα τρίτο είδος από objects. Έχει κανείς καμιά ιδέα; &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description></item></channel></rss>