2012-01-24 6 views
8

मेरे पास निम्न इंटरफ़ेस है।क्या यह एक सजावट या रणनीति पैटर्न है, या दो में से कोई नहीं?

PowerSwitch.java

public interface PowerSwitch { 
    public boolean powerOn(); 
    public boolean powerOff(); 
    public boolean isPowerOn(); 
} 

ऊपर इंटरफेस, तरीकों जो किसी भी अन्य कार्यक्षमता से प्राप्त किया जा सकता है की न्यूनतम सेट से मिलकर चाहिए संभव के रूप में अतिरिक्त PowerSwitch कार्यान्वयन को जोड़ने के लिए यह रूप में आसान बनाने के लिए।

मैं रन-टाइम में PowerSwitch इंटरफेस में कार्यक्षमता जोड़ने के (क्या सज्जाकार करते हैं) एक वर्ग है जो एक PowerSwitch उदाहरण के एक संरचना रखती है और कहते हैं नए तरीके बनाने के द्वारा, दो toggleOnOff (जैसे चाहते हैं) तरीकों नीचे। इस तरह मुझे केवल दो टॉगल विधियों को एक बार लागू करने की आवश्यकता है और यह सभी पावरस्विच कार्यान्वयन पर लागू होगा।

क्या यह एक अच्छी/बुरी आदत के रूप में माना जाता है? यदि बुरा है, तो कोई अन्य सिफारिशें?

यह वास्तव में सजावटी-पैटर्न का पालन नहीं करता क्योंकि यह अतिरिक्त विधियों को जोड़ता है। क्या यह एक रणनीति पैटर्न, या एक रचना पैटर्न है? या क्या इसका दूसरा पैटर्न नाम है? क्या "इंटरफ़ेस सजावट" जैसी कोई चीज़ है?

PowerSwitchDecorator.java

public class PowerSwitchDecorator { 
    private PowerSwitch ps; 

    public PowerSwitchDecorator(PowerSwitch ps) { 
     this.ps = ps; 
    } 

    public void toggleOnOff(int millis) throws InterruptedException{ 
     powerOn(); 
     Thread.sleep(millis); 
     powerOff(); 
    } 

    public void toggleOnOff(){ 
    powerOn(); 
    powerOff(); 
    } 

    public boolean powerOn() { 
     return ps.powerOn(); 
    } 

    public boolean powerOff() { 
     return ps.powerOff(); 
    } 

    public boolean isPowerOn() { 
     return ps.isPowerOn(); 
    } 
} 
+5

PowerSwitchDecorator PowerSwitch इंटरफ़ेस को लागू क्यों नहीं करता है? यह निश्चित रूप से ... – Ani

उत्तर

3

मामले तुम क्रम में अपने PowerSwitch उदाहरण को बढ़ाने के लिए की जरूरत है एक अच्छा अभ्यास है कि। मैं आपको सजावटी में पावरस्विच इंटरफेस को लागू करने की सलाह देता हूं। सजावटी पैटर्न का दूसरा नाम प्रॉक्सी पैटर्न है।

आप अपने पावरस्विच इंटरफ़ेस को विस्तारित करने वाले किसी अन्य इंटरफ़ेस में विस्तारित विधियों को परिभाषित कर सकते हैं। इससे सजावटी पर निर्भरता होने से बचेंगी जब इन विस्तारित तरीकों को बुलाया जाना आवश्यक है।

एक कक्षा का विस्तार करना एक अच्छा अभ्यास है जब आपको संकलन में व्यवहार को बढ़ाने या फिर से परिभाषित करने की आवश्यकता होती है।

+0

धन्यवाद! मेरे पास सजावटी पावरस्विच इंटरफ़ेस – etxalpo

0

सजावटकर्ता ने पावरस्विच इंटरफ़ेस को भी लागू किया है, तो यह वास्तव में एक सजावटी होगा। मैं इसे ऑब्जेक्ट एकत्रीकरण के रूप में वर्णित करता हूं।

7

यह है के रूप में, किसी भी कोड toggleOnOff(int) या toggleOnOff() तरीकों का उपयोग करना चाहता है कि PowerSwitchDecorator, नहीं PowerSwitch का एक उदाहरण की जरूरत जा रहा है। इस तरह के एक सजावट के उद्देश्य को हरा देता है जो ग्राहक के लिए पारदर्शी होना चाहिए।

यदि आप सभी विधियों को इन विधियों के लिए चाहते हैं, तो आपको उन्हें PowerSwitch इंटरफ़ेस में शामिल करना चाहिए।

फिर, जैसा कि @Ani पता चलता है, आप ऊपर PowerSwitchDecorator का विस्तार करने के PowerSwitch तो आप ऐसा कर सकते हैं संशोधित कर सकते हैं:

PowerSwitch switch = new PowerSwitchDecorator(new ConcretePowerSwitch()); 
switch.toggleOnOff(); 

अब आप PowerSwitchDecorator की क्षमताओं के साथ प्रकार PowerSwitch के एक चर है।

संपादित करें: ध्यान दें कि यदि आपको अपनी आवश्यकताओं को पूरा करता है तो आपको केवल एक स्थापित पैटर्न का उपयोग करना चाहिए। यदि आप अपने लिए काम करते हैं तो आप उस दृष्टिकोण का उपयोग कर सकते हैं जो आपने दिखाया है। इसे एक विशिष्ट पैटर्न में जूता-सींग करने की ज़रूरत नहीं है।

हालांकि आप किस प्रकार की वस्तु को पास करना चाहते हैं?

void connect(PowerSwitch powerSwitch, Appliance appliance); 

या तरीकों इस तरह:: यदि आप अपने एपीआई में इस तरह के तरीकों चाहते हैं

void connect(PowerSwitchDecorator powerSwitch, Appliance appliance); 

(माफ करना, वे नहीं कर रहे हैं बहुत अच्छा उदाहरण)

आप पूर्व चाहते हैं, तो प्रत्येक सुविधा सुविधा प्राप्त करने के लिए सभी को अपने PowerSwitch मैन्युअल रूप से 'सजाने' के लिए जाना होगा। यह अब आपके लिए सुविधाजनक हो सकता है लेकिन मुझे लगता है कि यह आपके कोड के उपयोगकर्ताओं के लिए असुविधाजनक होगा और वे शायद इसके साथ परेशान नहीं होंगे। यदि आप उत्तरार्द्ध चाहते हैं, तो आपको अपने विधि हस्ताक्षर में PowerSwitchDecorator टाइप करना होगा, जिसका अर्थ यह है कि आप हमेशा PowerSwitchDecorator एस से निपटते हैं और कच्चे PowerSwitch es नहीं।

+1

लागू करेगा लेकिन इसका मतलब यह नहीं होगा कि मुझे सभी शक्तियों के कार्यान्वयन में डमी विधियों (टॉगलऑनऑफ) को लागू करने की आवश्यकता है? और इसके अतिरिक्त, अगर मैं सजावटी में बाद में एक नई विधि जोड़ना चाहता हूं (चलो टॉगलऑफऑन कहें), तो मुझे इसे PowerSwitch इंटरफेस में जोड़ने और सभी मौजूदा पावरस्विच कार्यान्वयन को अपडेट करने की आवश्यकता है (क्योंकि वे अब संकलित नहीं होंगे)? शायद यह भी हो सकता है कि मेरे पास सभी शक्तियों तक पहुंच नहीं है स्वीच कार्यान्वयन (सेवा प्रदाता इंटरफ़ेस का हिस्सा हो सकता है)। – etxalpo

+1

etxalpo के रूप में, मैं असहमत हूं। सजावटी इंटरफ़ेस को सजाए गए इंटरफ़ेस को लागू करके, यह अभी भी उपयोगी है क्योंकि PowerSwitch के सभी क्लाइंट PowerSwitchDecorator का उपयोग कर सकते हैं। जैसे कि रीडर के सभी ग्राहक पारदर्शी रूप से BufferedReader का उपयोग कर सकते हैं। यह BufferedReader को अपनी विधियों को जोड़ने के लिए नहीं रोकता है (उदाहरण के लिए readLine()) और इस पैटर्न के लिए बेहद उपयोगी होना है। –

+0

हाँ यह सही है। आप शायद मूल टॉगल विधियों के साथ एक अमूर्त वर्ग चाहते हैं कि आपके सभी कार्यान्वयन से प्राप्त हो। फिर यदि आप टॉगलिंग का एक विशिष्ट तरीका चाहते हैं तो आप इसे सजाने के लिए तैयार कर सकते हैं। मैंने अपना जवाब संपादित किया, उम्मीद है कि यह मदद करता है;) –

0

यह पैटर्न में से कोई नहीं है।

एक सजावटी के पास ऑब्जेक्ट को लपेटने और क्लाइंट के लिए इंटरफ़ेस पारदर्शी बनाने वाली पहले से मौजूद कार्यक्षमता का विस्तार करने का इरादा है। एक BufferedInputstream एक उदाहरण है। ध्यान दें कि सजावटकर्ता को उसी प्रकार के इंटरफ़ेस को लागू करना चाहिए जैसा आप लपेट रहे हैं।

//Let Type be the interface that both the Decorator and DecoratedClass implements 
Type yourInstance = new Decorator(new DecoratedClass()); 

नोट प्रॉक्सी-पैटर्न, जहां मुख्य उद्देश्य एक वस्तु के लिए उपयोग को नियंत्रित करने के, जरूरी नहीं कि किसी अन्य वस्तु लपेटकर है से अंतर। इस मामले में आप प्रॉक्सी को एक ही इंटरफेस को लागू करने देंगे।

+0

क्या आपका मतलब है "ध्यान दें ..." और "अंतर ध्यान दें ..." जब आप कहते हैं "नहीं ..." और "अंतर नहीं ..."? –

+0

हां, टाइपो के लिए खेद है। धन्यवाद! –

0

कई पैटर्न अक्सर समान दिखते हैं, अंतर उनके उपयोग के इरादे में है। यहां इस विषय पर एक और सामान्य धागा है: When and How Strategy pattern can be applied instead of decorator pattern?

अपने कोड के साथ, अभी तक कोई वास्तविक अंतर नहीं है। यह एक रणनीति की तरह दिखता है, क्योंकि PowerSwitchDecorator केवल PowerSwitch पर काम (यानी एल्गोरिदम) का प्रतिनिधि है। यदि यह आपका इरादा है और वैकल्पिक पावरस्विच अलग-अलग तरीकों से टॉगल कर रहे हैं, तो रणनीति पैटर्न आपकी पसंद है।

यदि इसके बजाय आपके पास पावरस्विच का एक सेट है, तो प्रत्येक थोड़ी सी तरीके से टॉगलिंग को बढ़ाता है (टॉगलिंग सजाने) और इन पावरस्विच को घोंसला जा सकता है, तो आप एक सजावट को लागू कर रहे हैं। जैसा कि पहले कहा गया है, इस मामले में आपको सजावटकारों को प्रकार पदानुक्रम का हिस्सा बनने की भी आवश्यकता है।

0

मैं कहूंगा कि यह पैटर्न में से कोई नहीं है।

डेकोरेटर पैटर्न

डेकोरेटर पैटर्न किसी मौजूदा कार्यान्वयन के व्यवहार का विस्तार करने के लिए किया जाता है। उदाहरण के रूप में एक ग्राफिक विंडो लें, हो सकता है कि आप एक विंडो चाहते हों जिसमें स्क्रॉल बार हों। तो फिर तुम

public class ScrollBarsWindow : Window 
{ 
    private Window windowToDecorate; 
    public ScrollBarsWindow(Window windowToDecorate) 
    { 
     this.windowToDecorate = windowToDecorate; 
    } 

    public void Draw() 
    { 
     windowToDecorate.Draw(); 
     DrawScrollBars(); 
    } 

    public void DrawScrollBars() 
    { Draw the scroll bars } 
} 

रणनीति पैटर्न

रणनीति पैटर्न चुना रणनीति के आधार पर अलग काम करने के लिए प्रयोग किया जाता है की तरह एक वर्ग हो सकता है। मान लें कि आप कुछ कॉफी बना रहे हैं।आप की तरह कुछ हो सकता था:

public interface IMakeCoffeeStrategy 
{ 
    public Coffee MakeCoffee(); 
} 

public class CappuccinoStrategy : IMakeCoffeeStrategy 
{ 
    public Coffee MakeCoffee { make your cappuccion } 
} 

public class LatteStrategy : IMakeCoffeeStrategy 
{ 
    public Coffee MakeCoffee { make your latte } 
} 

public class Context 
{ 
    private IMakeCoffeeStrategy strategy; 
    public Context(IMakeCoffeeStrategy strategy) 
    { 
     this.strategy = strategy; 
    } 

    public Coffee MakeSomeCoffee() 
    { 
     return strategy.MakeCoffee(); 
    } 
} 

और

public class MyCoffeeMachine 
{ 
    public Coffee MakeCoffee(CoffeeType coffeeType) 
    { 
     if(coffeeType == CoffeeType.Latte) 
      return new Context(new LatteStrategy()).MakeSomeCoffee(); 
     else if(coffeeType == CoffeeType.Cappuccino) 
      return new Context(new CappuccinoStrategy()).MakeSomeCoffee(); 

     ... 
    } 
} 

की तरह उपयोग में अधिक जानकारी के लिए निम्न लिंक पढ़ें:

0

आपकी PowerSwitchDecorator कक्षा सजावटी नहीं है। आपका क्रियान्वयन Strategy_pattern के करीब है, भले ही आदेशों के समान Command_pattern

Decorator पैटर्न में, Decorator वास्तव में इंटरफ़ेस (अर्थात Component) को लागू करता है और अपनी कक्षा में एक ही नहीं कर रहा है।

वर्ग रेखाचित्र

enter image description here

पर एक नज़र ऊपर चित्र में है, Component एक अंतरफलक है। Decorator लागू Component इंटरफ़ेस और Composition के साथ इंटरफ़ेस शामिल है। सदस्य चर देखें - component

बेहतर समझ के लिए इन सवालों का संदर्भ लें:

Decorator Pattern for IO

Real World Example of the Strategy Pattern

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