2010-12-02 17 views
5

मैं this विकिपीडिया लेख देख रहा था, और नहीं समझ सकता है कि कैसे नरक कि काम कर रहा था। बस इसे देखकर कोड को समझने में सक्षम नहीं होने के कारण, मैं कोड को सी # (मैं हूं .नेट, माफ करना दोस्तों :)) को पोर्ट करने के लिए समर्पित हूं। बस कुछ मामूली संशोधन की आवश्यकता थी (विरासत और विस्तार, सुपर के लिए आधार, आदि) और ऐप चलाएं। मेरे आश्चर्य करने के लिए, मैं निम्नलिखित उत्पादन मिल गया:डेकोरेटर पैटर्न प्रश्न सी #/जावा

Cost: 1 Ingredient: Coffee 
Cost: 1 Ingredient: Coffee 
Cost: 1 Ingredient: Coffee 
Cost: 1 Ingredient: Coffee 

बस उत्सुक, किसी भी जावा देव मुझे बता सकते हैं कि यहाँ क्या अलग है और यही कारण है विकिपीडिया उदाहरण काम करता है (अगर यह निश्चित रूप से काम करता है के रूप में वे कहते हैं कि यह होता है,)।

namespace ConsoleApplication1 
{ 
class Program 
{ 
    static void Main(string[] args) 
    { 

    Coffee sampleCoffee = new SimpleCoffee(); 
    Console.WriteLine("Cost: " + sampleCoffee.getCost() + " Ingredient: " + sampleCoffee.getIngredient()); 

     sampleCoffee = new Milk(sampleCoffee); 
     Console.WriteLine("Cost: " + sampleCoffee.getCost() + " Ingredient: " + sampleCoffee.getIngredient()); 

     sampleCoffee = new Sprinkles(sampleCoffee); 
     Console.WriteLine("Cost: " + sampleCoffee.getCost() + " Ingredient: " + sampleCoffee.getIngredient()); 

     sampleCoffee = new Whip(sampleCoffee); 
     Console.WriteLine("Cost: " + sampleCoffee.getCost() + " Ingredient: " + sampleCoffee.getIngredient()); 

    Console.ReadKey(); 

    } 
} 



//The Coffee Interface defines the functionality of Coffee implemented by decorator 
public interface Coffee 
{ 

    double getCost(); // returns the cost of coffee 

    String getIngredient(); //returns the ingredients mixed with coffee 
} 

//implementation of simple coffee without any extra ingredients 
public class SimpleCoffee : Coffee 
{ 

    double cost; 
    String ingredient; 

    public SimpleCoffee() 
    { 
     cost = 1; 
     ingredient = "Coffee"; 
    } 

    public double getCost() 
    { 
     return cost; 
    } 

    public String getIngredient() 
    { 
     return ingredient; 
    } 
} 



//abstract decorator class - note that it implements coffee interface 
abstract public class CoffeeDecorator : Coffee 
{ 

    protected Coffee decoratedCoffee; 
    protected String ingredientSeparator; 

    public CoffeeDecorator(Coffee decoratedCoffee) 
    { 
     this.decoratedCoffee = decoratedCoffee; 
     ingredientSeparator = ", "; 
    } 

public CoffeeDecorator() 
{ 

} 

    public double getCost() //note it implements the getCost function defined in interface Coffee 
    { 
     return decoratedCoffee.getCost(); 
    } 

    public String getIngredient() 
    { 
     return decoratedCoffee.getIngredient(); 
    } 
} 

//Decorator Milk that mixes milk with coffee 
//note it extends CoffeeDecorator 
public class Milk : CoffeeDecorator 
{ 

    double cost; 
    String ingredient; 

    public Milk(Coffee decoratedCoffee) : base(decoratedCoffee) 
    { 
     cost = 0.5; 
     ingredient = "Milk"; 
    } 

    public double getCost() 
    { 
     return base.getCost() + cost; 
    } 

    public String getIngredient() 
    { 
     return base.getIngredient() + base.ingredientSeparator + ingredient; 
    } 
} 

//Decorator Whip that mixes whip with coffee 
//note it extends CoffeeDecorator 
public class Whip : CoffeeDecorator 
{ 

    double cost; 
    String ingredient; 

public Whip(Coffee decoratedCoffee) 
    : base(decoratedCoffee) 
    { 
     cost = 0.7; 
     ingredient = "Whip"; 
    } 

    public double getCost() 
    { 
     return base.getCost() + cost; 
    } 

    public String getIngredient() 
    { 
     return base.getIngredient() + base.ingredientSeparator + ingredient; 
    } 
} 

//Decorator Sprinkles that mixes sprinkles with coffee 
//note it extends CoffeeDecorator 
public class Sprinkles : CoffeeDecorator 
{ 

    double cost; 
    String ingredient; 

    public Sprinkles(Coffee decoratedCoffee) : base(decoratedCoffee) 
    { 

     cost = 0.2; 
     ingredient = "Sprinkles"; 
    } 

    public double getCost() 
    { 
    return base.getCost() + cost; 
    } 

    public String getIngredient() 
    { 
    return base.getIngredient() + base.ingredientSeparator + ingredient; 
    } 
} 

} 
+0

मुझे सी # पता नहीं है। लेकिन ऐसा लगता है कि आप अपनी विधियों को ओवरराइड नहीं करते हैं। –

+0

यहाँ http://msdn.microsoft.com/en-us/library/ms173152%28VS.80%29.aspx –

उत्तर

10

हाँ - जावा में डिफ़ॉल्ट रूप से वर्चुअल वर्चुअल हैं, लेकिन सी # में नहीं।

आप चेतावनी प्राप्त हो जाना चाहिए जब अपने कोड संकलन, 'नई' संशोधक के बारे में बात कर। आपको एक सुराग देना चाहिए था। वर्तमान में Milk (आदि) विधियां छिपाने या CoffeeDecorator में छायांकित हैं - उन्हें बहुरूप नहीं कहा जा रहा है।

आप override संशोधक के साथ तो स्पष्ट रूप से उन्हें Milk (आदि) में ओवरराइड CoffeeDecorator तरीकों virtual संशोधक के साथ आभासी बनाने की जरूरत चाहते हैं, और।

// In CoffeeDecorator 
public virtual double getCost() 
{ 
    return decoratedCoffee.getCost(); 
} 

// In Milk 
public override double getCost() 
{ 
    return base.getCost() + cost; 
} 
+0

के बारे में MSDN के लेख Nooo ... जॉन, आप 10 सेकेंड तेजी से मुझे तो थे: '( – Hinek

+0

aagghh।मुझे कंपाइलर को देखना चाहिए था :)। यह नहीं पता था कि डिफ़ॉल्ट रूप से जावा में सब कुछ आभासी है। जो मुझे एक और सवाल पर ले जाता है .. क्या आप जावा में "गैर" आभासी तरीकों को बना सकते हैं? –

+1

@ डैनियल पेरेज़, आप इसे 'अंतिम' घोषित कर सकते हैं। –

2

आप getCost और getIngredient virtual घोषित करने और व्युत्पन्न verions में override कीवर्ड का उपयोग करना भूल गए। जिस तरह से आपने इसे किया, आप बस विधियों को "ओवरलोड" करते हैं।

+2

यह वास्तव में अधिभारित नहीं है - यह छाया/छुपा रहा है। –

0

आप को लागू करने वर्ग CoffeeDecorator के getCost() विधि के बजाय 'getCost() विधि कम पड़ रहा है .. आप कैसे आप विधि अधिभावी रहे हैं पर देखने की जरूरत है।

0

यह थोड़ा वर्बोज़ उदाहरण है लेकिन मुझे लगता है कि मैं 2 लाइनों में पैटर्न को समझा सकता हूं। सजावटी पैटर्न आपको इंटरफेस के मौजूदा कार्यान्वयन को लपेटने की अनुमति देता है। पैटर्न का अन्य नाम रैपर है।

उदाहरण के लिए आप इंटरफ़ेस फू है:

interface Foo { 
    public int foo(); 
} 

class SimpleFoo implements Foo { 
    public int foo() { 
     return 1; 
    } 
} 

SimpleFoo.foo() हमेशा 1 रिटर्न;

class DoubleFoo implements Foo { 
    private Foo payload; 
    public DoubleFoo(Foo payload) { 
     this.payload = payload; 
    } 
    public int foo() { 
     return 2 * payload.foo(); 
    } 
} 

DoubleFoo.foo() पेलोड फू से सजाया गया:

यहाँ सरल decarator है। यह द्वारा 2.

परिणाम गुणा जाहिर है यह भी अपने स्वयं के कार्यान्वयन से पेलोड के कार्यान्वयन की जगह ले सकता। लेकिन यह पैटर्न का क्लासिक मामला नहीं है।

इस पद्धति के उपयोग के सबसे प्रसिद्ध उदाहरण जावा में आईओ है: नदियों, पाठकों और लेखकों सभी रैपर हैं। उदाहरण के लिए BufferedReader पेलोड रीडर को कार्यक्षमता जोड़ता है: यह डेटा को बफर में पढ़ता है।

संबंधित मुद्दे