Η επέκταση και τις δύο πλευρές ενός επισκέπτη / Bridge μοτίβο

ψήφοι
3

Ας πούμε ότι έχω μια ιεραρχία των κατηγοριών, ας χρησιμοποιήσουμε τα κλασικά Shapeπαραδείγματα:

abstract class Shape
Circle : Shape
Square : Shape

Έχω μια δεύτερη ιεραρχία των κατηγοριών renderer που χειρίζονται την απόδοση των σχημάτων με διαφορετικούς τρόπους:

abstract class ShapeRenderer
HtmlShapeRenderer : ShapeRenderer
WindowsFormsShapeRenderer : ShapeRenderer

Επιτρέποντας αυτά να ποικίλουν ανεξάρτητα θα παραδοσιακά περιλαμβάνει τη χρησιμοποίηση το μοτίβο Bridge. Επιτρέποντας την απόδοση ενέργειες που πρέπει να επεκταθεί χωρίς να τροποποιεί τις Shapeκατηγορίες που παραδοσιακά θα περιλαμβάνει το μοτίβο επισκέπτη.

Ωστόσο, και τα δύο από αυτά επικεντρώνονται αποκλειστικά στην επέκταση της πλευράς εφαρμογής και όχι από την πλευρά της αφαίρεσης. Πες Ήθελα να προσθέσω ένα νέο Shape, λένε Triangle- θα ήθελα να είναι σε θέση να υποστηρίξει καθιστώντας το Triangleεπίσης. Δεδομένου ότι τόσο ο επισκέπτης και το σχέδιο Γέφυρα βασίζονται σε «ισοπέδωση» της ιεραρχίας αφαίρεσης σε μια σειρά από μεθόδους, όπως:

public abstract class ShapeRenderer
{
     public abstract void RenderCircle(Circle c);
     public abstract void RenderSquare(Square s);
}

Ο μόνος τρόπος για να επεκταθεί η Shapeιεραρχία είναι να τροποποιήσει τον κώδικα της βάσης ShapeRendererκατηγορίας, το οποίο είναι ένα σπάσιμο αλλαγή.

Jon, να διευκρινίσει: Χρήση του Bridge ή επισκέπτη επιτρέπει στους πελάτες να παρέχουν εναλλακτικές υλοποιήσεις απόδοση, αλλά απαιτεί από αυτούς να ξέρετε για όλες τις πιθανές σχήματα. Αυτό που θα ήθελα να είναι σε θέση να κάνουμε είναι να επιτρέψει στους πελάτες να επίσης να είναι σε θέση να επεκτείνει την Shapeτάξη και να απαιτήσει να παρέχει μια απόδοση της εφαρμογής για την νέα κατηγορία τους. Με αυτό τον τρόπο, τα υπάρχοντα κώδικα μπορεί να λειτουργήσει με οποιοδήποτε τύπο Shape, χωρίς να ανησυχείτε για τα στοιχεία της παροχής τους.

Είναι μια κοινή λύση σε αυτό το είδος του προβλήματος που μπορούν να χρησιμοποιηθούν σε C # εκεί;

Δημοσιεύθηκε 09/12/2008 στις 18:00
πηγή χρήστη
Σε άλλες γλώσσες...                            


4 απαντήσεις

ψήφοι
2

Τι λέτε για το σχέδιο στρατηγικής ; Σε περίπτωση που η στρατηγική είναι μια αναφορά σε μια εφαρμογή RenderEngine. Όταν θέλετε να προσθέσετε ένα νέο σχήμα, μπορείτε να δημιουργήσετε μια νέα εφαρμογή των κινητήρων απόδοσης που γνωρίζουμε για τη νέα εφαρμογή σχήμα και υλοποιεί την αντίστοιχη λειτουργία απόδοσης. Μπορείτε να προσθέσετε μια εικονική λειτουργία στο σχήμα που λειτουργεί ως βοηθητική λειτουργία για να επιλέξετε τη σωστή λειτουργία rendering σχήμα - δηλαδή τον κύκλο αντικείμενα καλέστε το () συνάρτηση renderCircle κ.λπ.

Στην C ++ που μπορεί να μοιάζει κάπως έτσι:

class Triangle : public Shape
{
  public:
      Triangle( const RenderEngine& whichRenderEngine );
      void render( void ) { renderStrategy->renderTriangle( *this );

  private:
      RenderEngine* renderStrategy;
};

class TriangleRender : HTMLShapeRender
{
   public:
      // if inheriting from concrete class, all other rendering functions 
      // already exist... otherwise re-implement them here.

      void renderTriangle( const Triangle& t ) { /* impl */ }
};

HTMLRenderer r; // doesn't know about Triangles.
Circle c( &r );
c.render();

Square s( &r );
s.render();

// Now we add Triangle
TriangleRenderer tr;
Triangle t( &tr );
t.render();

Square s2( &tr );  // tr still knows how to render squares... 
s2.render();
Απαντήθηκε 10/12/2008 στις 04:50
πηγή χρήστη

ψήφοι
2

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

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

Τι είδους αλλαγές μη-σπάσιμο είναι πραγματικά ελπίζουν να επιτύχουν;

Απαντήθηκε 09/12/2008 στις 18:17
πηγή χρήστη

ψήφοι
1

Η λύση μου εδώ θα ήταν σχεδόν σίγουρα ήταν να χρησιμοποιήσετε ένα Abstract Factory, οπότε θα ήθελα να φορτώσει ένα λεξικό της ShapeRenderers πληκτρολογηθεί από τον τύπο, όπου το είδος είναι μια υπο-κατηγορία σχήμα και αφήστε το εργοστάσιο παρέχει το ShapeRenderer που απαιτείται για κάθε σχήμα (και ενδεχομένως πλατφόρμα, π.χ.. Παράθυρο, Web, iPhone).

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

Απαντήθηκε 09/12/2008 στις 18:58
πηγή χρήστη

ψήφοι
1

Σχεδιάστε σε ένα όχι interface μια εφαρμογή.

Γεια σου - έχω να χρησιμοποιήσει την ίδια απάντηση δύο φορές σήμερα (υποθέτω ότι είναι αμφισβητήσιμο ότι Renderer είναι μια εφαρμογή) ...

Δεν είμαι σίγουρος ότι θα πάει με την κατηγορία ShapeRenderer. Τι γίνεται με την IRenderHTML, IRenderWindows που υλοποιούνται από τις τάξεις σχήμα;

Μπορείτε να πάρετε επεκτασιμότητα με τα σχήματα, καθώς και με τις Renderings.

Νομίζω ότι μπορεί να είναι καλύτερα OO να πω hey κύκλο πάει να καταστήσει τον εαυτό σας, παρά να περάσει τον κύκλο σε μια κατηγορία χρησιμότητα για την απόδοση. Θα μπορούσατε να προσθέσετε εύκολα νέα σχήματα και νέες αποδόσεις, αφήνοντας τα σχήματα κάνουν την απόδοση τους.

Απαντήθηκε 09/12/2008 στις 18:22
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more