2017-02-13 9 views
5

मैंने सजावटी डिजाइन पैटर्न का एक उदाहरण पढ़ा। मुझे समझ में आया कि यह डिज़ाइन पैटर्न गतिशील रूप से एक विशेष उदाहरण के व्यवहार को संशोधित करता है। उदाहरण जो मैंने नीचे दिया है वह भी समझ में आता है। जिस बिंदु को मैं समझ नहीं पाया वह यह है कि जब मैं दूध वस्तु पर c.getCost() पर कॉल करता हूं, तो यह 1.5 लौटाता है। केवल Simplecoffee का getCost() 1 लौटाता है, लेकिन दूध वापसी पर c.getCost कहां से आता है?सजावटी पैटर्न श्रृंखला विधि कैसे कॉल करता है?

क्या कोई भी Milk कक्षा और Simplecoffee कक्षा के बीच के लिंक को समझ सकता है, और विधि के निष्पादन को getCost() दूध वस्तु के साथ बुलाए जाने पर कैसे बहती है? getCost() विधि वापसी 1.5 कैसे करता है?

//Decorator Design Pattern 
interface Coffee { 
    public double getCost(); 

    public String getIngredients(); 
} 

class Simplecoffee implements Coffee { 
    public double getCost() { 
     return 1; 
    } 

    public String getIngredients() { 
     return "Coffee"; 
    } 
} 

abstract class CoffeeDecorator implements Coffee { 
    protected Coffee decoratedcoffee; 
    protected String ingredientseparator = ":"; 

    public CoffeeDecorator(Coffee decoratedcoffee) { 

     this.decoratedcoffee = decoratedcoffee; 
    } 

    public double getCost() { 
     return decoratedcoffee.getCost(); 
    } 

    public String getIngredients() { 
     return decoratedcoffee.getIngredients(); 
    } 
} 

class Milk extends CoffeeDecorator { 

    public Milk(Coffee decoratedcoffee) { 

     super(decoratedcoffee); 
     System.out.println("Milk Constructor"); 
    } 

    public double getCost() { 
     return super.getCost() + 0.5; 
    } 

    public String getIngredients() { 
     return super.getIngredients() + ingredientseparator + "milk"; 
    } 
} 

public class Decorator {  
    public static void main(String[] ar) { 
     System.out.println("calling simplecoffee in main"); 
     Coffee c = new Simplecoffee(); 
     System.out.println("Cost:" + c.getCost()); 
     c = new Milk(c); 
     System.out.println("Cost:" + c.getCost()); 
    }  
} 
+0

आप एक 'Thread.dumpStack()' 'की getCost' विधि में' Simplecoffee' पता लगाने के लिए डाल सकता है। –

+0

असल में, जब आपने सी = नया दूध कहा (सी) आप कॉफीडिकोरेटर कन्स्ट्रक्टर को विरासत के माध्यम से बुला रहे हैं, जो सिंपलकोफी इंस्टेंस को इसके क्षेत्र (इंटरफ़ेस कॉफी के माध्यम से संदर्भित) के रूप में सेट करता है, और सजाए गए coffee.getCost() को कॉल करता है; विरासत के माध्यम से अपनी मूल विधि में जाता है जो 1 देता है और 0.5 – drgPP

+0

जोड़ता है "दूध वस्तु के साथ बुलाए जाने पर विधि कैसे बहती है" एलओएल – Reg

उत्तर

5

कैसे getCost() विधि रिटर्न 1.5?

Milk पहले कॉल decoratedcoffee पर getCost तरीका है जिसके SimpleCoffee लिए एक संदर्भ है में getCost() विधि। इसलिए विधि SimpleCoffee से विधि को कॉल करेगा जो 1 लौटाएगा (पढ़ें: रनटाइम पॉलीमोर्फिज्म)। इसके बाद, Milk में getCost विधि इस कॉल के रिटर्न मान कहते हैं (यानी 1) इस प्रकार आप के रूप में 1.5

यह डेकोरेटर पैटर्न के पूरे मुद्दे है परिणाम दे रही है 0.5 करने के लिए। सजावटी का उपयोग मौजूदा श्रृंखला में एक नई वस्तु को लपेटकर विधि कॉल की श्रृंखला बनाने के लिए किया जाता है।

1

मैं आपके दूध वर्ग को मिल्कडेकॉफी के रूप में नामित करूंगा। एक सजावटी मूल वस्तु को लपेटकर और अधिक विशेषताओं को जोड़ता है, साथ ही साथ मूल ऑब्जेक्ट के समान इंटरफ़ेस से संबंधित होता है, ताकि आपका ग्राहक कोड यह जानने के बिना काम कर सके कि यह कॉफी (मूल श्रेणी) या milkedcoffee (सजावट) है या आइस्ड कॉफी (एक और सजावट)। तो आपके उदाहरण में सजाए गए कॉफी को कॉफी होना चाहिए, दूध, चीनी जैसे कॉफी पर कोई अतिरिक्त नहीं होना चाहिए .. आदि

अपने मूल प्रश्न का उत्तर देने के लिए, यदि आपका तर्क जोड़ने के लिए वापसी मूल्य 1.5 ठीक दिखता है .5 जब लागत एक कॉफी (MilkedCoffee के रूप में सजाया दूसरे शब्दों में) दूध के साथ परोसा जाता है

1

हमें नजर डालते हैं और कोड के इस टुकड़े को समझने:

coffee c = new simplecoffee(); 
System.out.println("Cost:" + c.getCost()); 
  • एक simplecoffee वस्तु बनाएँ और c के लिए असाइन करें । (के बाद से simplecoffeeकॉफी इंटरफेस के एक कार्यान्वयन है, कोई समस्या नहीं)
  • cकॉफी टाइप करने के लिए घोषित किया जाता है।

अगला चरण:

c = new milk(c); 
System.out.println("Cost:" + c.getCost()); 
  • एक दूध वस्तु बनाएं और नया दूध वस्तु को c आवंटित (c के पुराने मूल्य के ऊपर लिख)।
  • दूध एक अमूर्त वर्ग coffeedecorator जो भी लागू करता कॉफी इंटरफ़ेस फैली हुई है।
  • सरलकॉफी उपर्युक्त वस्तु को दूध कक्षा के अंदर एक आवृत्ति चर के लिए असाइन किया गया है।

    public double getCost(){ 
    
         return super.getCost() + 0.5; 
        } 
    
    • super.getCost()coffeedecorator कक्षा में कार्यान्वित किया जाता है:

    milk.getCost() जो पिछले प्रिंट से पहले कहा जाता है के कार्यान्वयन पर विचार करें। यह कॉफी उदाहरण के अंदर getCost() विधि को बस कॉल करता है।

  • हमारे मामले में यह simplecoffee जो लागत 1.
  • दूध लागत 0.5 है।

तो आप 1.5 मिलकर मिलते हैं।

ग्रेट्स एलन।

0

क्या कोई दूध मिल्क क्लास और सिंपलकोफी क्लास के बीच के लिंक को समझ सकता है और विधि वस्तु के निष्पादन को कैसे प्राप्त करता है() दूध वस्तु के साथ बुलाया जाता है। GetCost() विधि 1.5 कैसे लौटाता है?

visualization of the Decorator calls in Head First Design Patterns से बेहतर करना मुश्किल है। नीचे हरे तीर का पालन करें। getCost() पर कॉल घोंसला हैं, और वापसी मूल्य भी हरे रंग में दिखाए जाते हैं। छवि यह भी दिखाती है कि कैसे MilkSimplecoffee कक्षा wraps।

enter image description here

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