2013-04-18 17 views
5

Questo thread, Decorator pattern implementation, ha un'implementazione di un decoratore che utilizza classi astratte. Non mi piace per il semplice fatto che un CondimentDecorator NON è una bevanda nell'implementazione fornita qui. Io userei invece le interfacce. Le classi astratte non sono migliori per l'is-a, le relazioni e le interfacce migliori per l'has-a?Decoratori C#: interfacce o classi astratte?

public interface IBeverage 
{ 
    // get a description of the beverage 
    String Description { get; } 

    // calculate cost of the beverage 
    double Cost { get; } 
} 

// HouseBlend coffee implements IBeverage 
public class HouseBlend : IBeverage 
{ 
    private string description; 
    public String Description 
    { 
     get { return description; } 
    } 

    private double cost; 
    public double Cost 
    { 
     get { return cost; } 
    } 

    // Constructor 
    public HouseBlend() { description = "House Blend"; cost = 0.89; } 
} 

// DarkRoast coffee implements IBeverage 
public class DarkRoast : IBeverage 
{ 
    private string description; 
    public String Description 
    { 
     get { return description; } 
    } 

    private double cost; 
    public double Cost 
    { 
     get { return cost; } 
    } 

    // Constructor 
    public DarkRoast() { description = "Dark Roast"; cost = 1.10; } 
} 

// Mocha is a Decorator 
public class Mocha 
{ 
    // Mocha has-a Beverage 
    private IBeverage m_beverage; 

    private string description; 
    public String Description 
    { 
     get { return description; } 
    } 

    private public double Cost 
    { 
     get { return cost; } 
    } 

    // Constructor binds the object passed to member var 
    public Mocha(IBeverage beverage) 
    { 
     m_beverage = beverage; // not necessary for the purpose of this example 
     description = m_beverage.Description + ", Mocha"; 
     cost = 0.20 + m_beverage.Cost; 
    } 
} 

Use like this: 
    Mocha mhb = new Mocha(new HouseBlend()); // house blend with mocha flavor 
+0

Questa è probabilmente una soluzione migliore per programmers.stackexchange.com –

+0

Sono completamente d'accordo, ma non era questo il punto della domanda a cui ti riferisci. –

+2

Sì, masterizzando la tua unica e unica classe base su qualcosa che non è un-una relazione è una cattiva idea. –

risposta

3

Entrambe le basi e le interfacce sono frequentemente utilizzate per modellare is-a relazioni. Anche un'interfaccia semplice come IDisposable può essere intesa come "è un oggetto con un ciclo di vita controllato manualmente", un "usa e getta". Le differenze più tangibili sono nel fatto che l'implementazione di base oi campi di dati siano consentiti; e nella loro capacità di combinare più gerarchie.

Ora, quando si implementa lo modello, di solito si dispone di informazioni sufficienti per verificare se sono necessari o meno campi di dati. Tuttavia, difficilmente sarai in grado di escludere un futuro bisogno di coinvolgere le stesse classi in schemi aggiuntivi man mano che il tuo software cresce. Da questa prospettiva, una preferenza generale delle interfacce rispetto alle classi astratte offre maggiore flessibilità a lungo termine - ogni volta che si ha una scelta.

Per la natura di un decoratore, avete una scelta. I componenti in genere non hanno un ordine predefinito di come dovrebbero nidificare. Se lo facessero, useresti direttamente l'ereditarietà invece dei componenti. Quindi dovresti preferire le interfacce per comporre un decoratore.

Ciò detto, anche l'argomento originale è valido. I componenti del decoratore (caratteristiche) possono essere interpretati come se fosse una relazione, se lo desideri; ma non è il modo più naturale di guardarli.

Problemi correlati