मैं GOF में प्रलेखित के रूप में डेकोरेटर पैटर्न का अध्ययन कर रहा था ।
कृपया, डेकोरेटर पैटर्न को समझने में मेरी मदद करें । क्या कोई उपयोग-मामले का उदाहरण दे सकता है कि यह वास्तविक दुनिया में कहां उपयोगी है?
मैं GOF में प्रलेखित के रूप में डेकोरेटर पैटर्न का अध्ययन कर रहा था ।
कृपया, डेकोरेटर पैटर्न को समझने में मेरी मदद करें । क्या कोई उपयोग-मामले का उदाहरण दे सकता है कि यह वास्तविक दुनिया में कहां उपयोगी है?
जवाबों:
डेकोरेटर पैटर्न गतिशील रूप से किसी भी वस्तु में जिम्मेदारियों को जोड़ने का एक उद्देश्य प्राप्त करता है।
पिज्जा की दुकान के एक मामले पर विचार करें। पिज्जा की दुकान में वे कुछ पिज्जा किस्में बेचेंगे और वे मेनू में टॉपिंग भी प्रदान करेंगे। अब एक ऐसी स्थिति की कल्पना करें जिसमें यदि पिज्जा शॉप को पिज्जा और टॉपिंग के प्रत्येक संयोजन के लिए मूल्य प्रदान करना है। यहां तक कि अगर चार बुनियादी पिज्जा और 8 अलग टॉपिंग हैं, तो आवेदन पिज्जा और टॉपिंग के इन सभी ठोस संयोजन को बनाए रखने के लिए पागल हो जाएगा।
यहां डेकोरेटर पैटर्न आता है।
डेकोरेटर पैटर्न के अनुसार, आप सजावट के रूप में टॉपिंग को लागू करेंगे और पिज्जा को उन टॉपिंग्स के डेकोरेटर्स द्वारा सजाया जाएगा। व्यावहारिक रूप से प्रत्येक ग्राहक अपनी इच्छा की टॉपिंग चाहता है और अंतिम बिल-राशि आधार पिज्जा से बना होगा और इसके अलावा टॉपिंग का आदेश दिया जाएगा। प्रत्येक टॉपिंग डेकोरेटर को पिज्जा के बारे में पता होगा कि यह सज रहा है और इसकी कीमत है। GetPrice () टॉपिंग ऑब्जेक्ट का तरीका पिज्जा और टॉपिंग दोनों का संचयी मूल्य लौटाएगा।
यहां ऊपर दिए गए स्पष्टीकरण का एक कोड-उदाहरण है।
public abstract class BasePizza
{
protected double myPrice;
public virtual double GetPrice()
{
return this.myPrice;
}
}
public abstract class ToppingsDecorator : BasePizza
{
protected BasePizza pizza;
public ToppingsDecorator(BasePizza pizzaToDecorate)
{
this.pizza = pizzaToDecorate;
}
public override double GetPrice()
{
return (this.pizza.GetPrice() + this.myPrice);
}
}
class Program
{
[STAThread]
static void Main()
{
//Client-code
Margherita pizza = new Margherita();
Console.WriteLine("Plain Margherita: " + pizza.GetPrice().ToString());
ExtraCheeseTopping moreCheese = new ExtraCheeseTopping(pizza);
ExtraCheeseTopping someMoreCheese = new ExtraCheeseTopping(moreCheese);
Console.WriteLine("Plain Margherita with double extra cheese: " + someMoreCheese.GetPrice().ToString());
MushroomTopping moreMushroom = new MushroomTopping(someMoreCheese);
Console.WriteLine("Plain Margherita with double extra cheese with mushroom: " + moreMushroom.GetPrice().ToString());
JalapenoTopping moreJalapeno = new JalapenoTopping(moreMushroom);
Console.WriteLine("Plain Margherita with double extra cheese with mushroom with Jalapeno: " + moreJalapeno.GetPrice().ToString());
Console.ReadLine();
}
}
public class Margherita : BasePizza
{
public Margherita()
{
this.myPrice = 6.99;
}
}
public class Gourmet : BasePizza
{
public Gourmet()
{
this.myPrice = 7.49;
}
}
public class ExtraCheeseTopping : ToppingsDecorator
{
public ExtraCheeseTopping(BasePizza pizzaToDecorate)
: base(pizzaToDecorate)
{
this.myPrice = 0.99;
}
}
public class MushroomTopping : ToppingsDecorator
{
public MushroomTopping(BasePizza pizzaToDecorate)
: base(pizzaToDecorate)
{
this.myPrice = 1.49;
}
}
public class JalapenoTopping : ToppingsDecorator
{
public JalapenoTopping(BasePizza pizzaToDecorate)
: base(pizzaToDecorate)
{
this.myPrice = 1.49;
}
}
यह एक मौजूदा वस्तु को गतिशील रूप से, या डेकोरेटर पैटर्न में नए व्यवहार को जोड़ने का एक सरल उदाहरण है। जावास्क्रिप्ट जैसी गतिशील भाषाओं की प्रकृति के कारण, यह पैटर्न भाषा का हिस्सा बन जाता है।
// Person object that we will be decorating with logging capability
var person = {
name: "Foo",
city: "Bar"
};
// Function that serves as a decorator and dynamically adds the log method to a given object
function MakeLoggable(object) {
object.log = function(property) {
console.log(this[property]);
}
}
// Person is given the dynamic responsibility here
MakeLoggable(person);
// Using the newly added functionality
person.log('name');
switch
या एक साधारण के अंदर if
, आप यह दावा करने में सक्षम होंगे कि यह गतिशील रूप से कक्षा में व्यवहार को जोड़ने का एक बढ़िया उदाहरण है। लेकिन, हमें इस पैटर्न में डेकोरेटर और सजी हुई वस्तुओं को परिभाषित करने के लिए कम से कम दो वर्गों की आवश्यकता है।
यह ध्यान देने योग्य है कि जावा i / o मॉडल डेकोरेटर पैटर्न पर आधारित है। इस पाठक के शीर्ष पर उस पाठक के शीर्ष पर लेयरिंग ... सज्जाकार का एक वास्तविक वास्तविक उदाहरण है।
उदाहरण - परिदृश्य- मान लीजिए कि आप एक एन्क्रिप्शन मॉड्यूल लिख रहे हैं। यह एन्क्रिप्शन डेस - डेटा एन्क्रिप्शन मानक का उपयोग करके स्पष्ट फ़ाइल को एन्क्रिप्ट कर सकता है। इसी तरह, एक सिस्टम में आपके पास एन्क्रिप्शन एईएस के रूप में हो सकता है - एडवांस एन्क्रिप्शन मानक। इसके अलावा, आपके पास एन्क्रिप्शन का संयोजन हो सकता है - पहले डेस, फिर एईएस। या आपके पास पहले एईएस हो सकता है, फिर डीईएस।
चर्चा- आप इस स्थिति को कैसे पूरा करेंगे? आप ऐसे संयोजनों का उद्देश्य नहीं बना सकते हैं - उदाहरण के लिए - एईएस और डीईएस - कुल 4 संयोजन। इस प्रकार, आपको 4 अलग-अलग ऑब्जेक्ट्स की आवश्यकता है यह जटिल हो जाएगा क्योंकि एन्क्रिप्शन प्रकार बढ़ जाएगा।
समाधान - रन समय पर जरूरत के आधार पर स्टैक - संयोजन का निर्माण करते रहें। इस स्टैक दृष्टिकोण का एक और लाभ यह है कि आप इसे आसानी से खोल सकते हैं।
यहाँ समाधान है - C ++ में।
सबसे पहले, आपको आधार वर्ग की आवश्यकता है - स्टैक की एक मौलिक इकाई। आप स्टैक के आधार के रूप में सोच सकते हैं। इस उदाहरण में, यह स्पष्ट फ़ाइल है। चलो हमेशा बहुरूपता का पालन करें। इस मूलभूत इकाई का पहला इंटरफ़ेस वर्ग बनाएं। इस तरह, आप इसे अपनी इच्छानुसार कार्यान्वित कर सकते हैं। इसके अलावा, आपको इस मूलभूत इकाई को शामिल करते समय निर्भरता के बारे में सोचने की आवश्यकता नहीं है।
यहाँ इंटरफ़ेस वर्ग है -
class IclearData
{
public:
virtual std::string getData() = 0;
virtual ~IclearData() = 0;
};
IclearData::~IclearData()
{
std::cout<<"Destructor called of IclearData"<<std::endl;
}
अब, इस इंटरफ़ेस वर्ग को लागू करें -
class clearData:public IclearData
{
private:
std::string m_data;
clearData();
void setData(std::string data)
{
m_data = data;
}
public:
std::string getData()
{
return m_data;
}
clearData(std::string data)
{
setData(data);
}
~clearData()
{
std::cout<<"Destructor of clear Data Invoked"<<std::endl;
}
};
अब, चलो एक डेकोरेटर एब्स्ट्रैक्ट क्लास बनाते हैं - जिसे किसी भी प्रकार के स्वाद को बनाने के लिए बढ़ाया जा सकता है - यहाँ स्वाद एन्क्रिप्शन प्रकार है। यह डेकोरेटर एब्स्ट्रैक्ट क्लास बेस क्लास से संबंधित है। इस प्रकार, डेकोरेटर "एक प्रकार का इंटरफ़ेस क्लास है। इस प्रकार, आपको विरासत का उपयोग करने की आवश्यकता है।
class encryptionDecorator: public IclearData
{
protected:
IclearData *p_mclearData;
encryptionDecorator()
{
std::cout<<"Encryption Decorator Abstract class called"<<std::endl;
}
public:
std::string getData()
{
return p_mclearData->getData();
}
encryptionDecorator(IclearData *clearData)
{
p_mclearData = clearData;
}
virtual std::string showDecryptedData() = 0;
virtual ~encryptionDecorator() = 0;
};
encryptionDecorator::~encryptionDecorator()
{
std::cout<<"Encryption Decorator Destructor called"<<std::endl;
}
अब, चलो एक ठोस डेकोरेटर वर्ग बनाते हैं - एन्क्रिप्शन प्रकार - एईएस -
const std::string aesEncrypt = "AES Encrypted ";
class aes: public encryptionDecorator
{
private:
std::string m_aesData;
aes();
public:
aes(IclearData *pClearData): m_aesData(aesEncrypt)
{
p_mclearData = pClearData;
m_aesData.append(p_mclearData->getData());
}
std::string getData()
{
return m_aesData;
}
std::string showDecryptedData(void)
{
m_aesData.erase(0,m_aesData.length());
return m_aesData;
}
};
अब, मान लें कि डेकोरेटर टाइप DES है -
const std :: string desEncrypt = "डेस एनक्रिप्टेड";
class des: public encryptionDecorator
{
private:
std::string m_desData;
des();
public:
des(IclearData *pClearData): m_desData(desEncrypt)
{
p_mclearData = pClearData;
m_desData.append(p_mclearData->getData());
}
std::string getData(void)
{
return m_desData;
}
std::string showDecryptedData(void)
{
m_desData.erase(0,desEncrypt.length());
return m_desData;
}
};
आइए इस डेकोरेटर वर्ग का उपयोग करने के लिए एक क्लाइंट कोड बनाते हैं -
int main()
{
IclearData *pData = new clearData("HELLO_CLEAR_DATA");
std::cout<<pData->getData()<<std::endl;
encryptionDecorator *pAesData = new aes(pData);
std::cout<<pAesData->getData()<<std::endl;
encryptionDecorator *pDesData = new des(pAesData);
std::cout<<pDesData->getData()<<std::endl;
/** unwind the decorator stack ***/
std::cout<<pDesData->showDecryptedData()<<std::endl;
delete pDesData;
delete pAesData;
delete pData;
return 0;
}
आप निम्न परिणाम देखेंगे -
HELLO_CLEAR_DATA
Encryption Decorator Abstract class called
AES Encrypted HELLO_CLEAR_DATA
Encryption Decorator Abstract class called
DES Encrypted AES Encrypted HELLO_CLEAR_DATA
AES Encrypted HELLO_CLEAR_DATA
Encryption Decorator Destructor called
Destructor called of IclearData
Encryption Decorator Destructor called
Destructor called of IclearData
Destructor of clear Data Invoked
Destructor called of IclearData
यहां यूएमएल आरेख है - इसका वर्ग प्रतिनिधित्व। मामले में, आप कोड को छोड़ना चाहते हैं और डिज़ाइन पहलू पर ध्यान केंद्रित करना चाहते हैं।
strategy pattern
?
डेकोरेटर पैटर्न आपको इस ऑब्जेक्ट के अन्य समान उपवर्गों के साथ पीछा करके अपनी वस्तु की कार्यक्षमता को बदलने या कॉन्फ़िगर करने में मदद करता है।
सबसे अच्छा उदाहरण java.io पैकेज में InputStream और OutputStream कक्षाएं होंगी
File file=new File("target","test.txt");
FileOutputStream fos=new FileOutputStream(file);
BufferedOutputStream bos=new BufferedOutputStream(fos);
ObjectOutputStream oos=new ObjectOutputStream(bos);
oos.write(5);
oos.writeBoolean(true);
oos.writeBytes("decorator pattern was here.");
//... then close the streams of course.
जावा में डेकोरेटर डिज़ाइन पैटर्न क्या है।
GoF पुस्तक से डेकोरेटर पैटर्न की औपचारिक परिभाषा (डिजाइन पैटर्न: पुन: प्रयोज्य वस्तु-उन्मुख सॉफ्टवेयर के तत्व, 1995, पियर्सन एजुकेशन, इंक। पियर्सन एडिसन वेस्ले के रूप में प्रकाशन) का कहना है कि आप कर सकते हैं,
"गतिशील रूप से एक वस्तु के लिए अतिरिक्त जिम्मेदारियों को संलग्न करें। सज्जाकार कार्यक्षमता बढ़ाने के लिए उपवर्ग के लिए एक लचीला विकल्प प्रदान करते हैं।"
मान लीजिए कि हमारे पास एक पिज्जा है और हम इसे चिकन मसाला, प्याज और मोज़ेरेला चीज़ जैसे टॉपिंग से सजाना चाहते हैं। आइए देखें कि इसे जावा में कैसे लागू किया जाए ...
जावा में डेकोरेटर डिजाइन पैटर्न को लागू करने का तरीका प्रदर्शित करने के लिए कार्यक्रम।
Pizza.java:
<!-- language-all: lang-html -->
package com.hubberspot.designpattern.structural.decorator;
public class Pizza {
public Pizza() {
}
public String description(){
return "Pizza";
}
}
package com.hubberspot.designpattern.structural.decorator;
public abstract class PizzaToppings extends Pizza {
public abstract String description();
}
package com.hubberspot.designpattern.structural.decorator;
public class ChickenMasala extends PizzaToppings {
private Pizza pizza;
public ChickenMasala(Pizza pizza) {
this.pizza = pizza;
}
@Override
public String description() {
return pizza.description() + " with chicken masala, ";
}
}
package com.hubberspot.designpattern.structural.decorator;
public class MozzarellaCheese extends PizzaToppings {
private Pizza pizza;
public MozzarellaCheese(Pizza pizza) {
this.pizza = pizza;
}
@Override
public String description() {
return pizza.description() + "and mozzarella cheese.";
}
}
package com.hubberspot.designpattern.structural.decorator;
public class Onion extends PizzaToppings {
private Pizza pizza;
public Onion(Pizza pizza) {
this.pizza = pizza;
}
@Override
public String description() {
return pizza.description() + "onions, ";
}
}
package com.hubberspot.designpattern.structural.decorator;
public class TestDecorator {
public static void main(String[] args) {
Pizza pizza = new Pizza();
pizza = new ChickenMasala(pizza);
pizza = new Onion(pizza);
pizza = new MozzarellaCheese(pizza);
System.out.println("You're getting " + pizza.description());
}
}
मैंने अपने काम में बड़े पैमाने पर डेकोरेटर पैटर्न का उपयोग किया है। मैंने अपने ब्लॉग पर एक पोस्ट बनाई कि लॉगिंग के साथ इसका उपयोग कैसे करें।
डेकोरेटर पैटर्न आपको गतिशील रूप से वस्तुओं में व्यवहार जोड़ने देता है।
आइए एक उदाहरण लेते हैं जहां आपको एक ऐप बनाने की आवश्यकता होती है जो विभिन्न प्रकार के बर्गर की कीमत की गणना करता है। आपको बर्गर के विभिन्न रूपों को संभालने की आवश्यकता है, जैसे "बड़े" या "पनीर के साथ", जिनमें से प्रत्येक की कीमत मूल बर्गर के सापेक्ष है। जैसे पनीर के साथ बर्गर के लिए $ 10 जोड़ें, बड़े बर्गर के लिए अतिरिक्त $ 15 जोड़ें, आदि।
इस मामले में आपको इनको संभालने के लिए उपवर्ग बनाने का प्रलोभन दिया जा सकता है। हम रूबी में इसे व्यक्त कर सकते हैं:
class Burger
def price
50
end
end
class BurgerWithCheese < Burger
def price
super + 15
end
end
उपरोक्त उदाहरण में, बर्गरविथशेसी वर्ग बर्गर से विरासत में मिला है, और सुपर क्लास में परिभाषित मूल्य में $ 15 जोड़ने के लिए मूल्य पद्धति को ओवरराइड करता है। आप एक लार्जबर्गर क्लास भी बनाएंगे और बर्गर के सापेक्ष कीमत निर्धारित करेंगे। लेकिन आपको "बड़े" और "पनीर के साथ" के संयोजन के लिए एक नए वर्ग को परिभाषित करने की भी आवश्यकता है।
अब क्या होगा अगर हमें "बर्गर विद फ्राइज़" परोसना पड़े? हमारे पास उन संयोजनों को संभालने के लिए पहले से ही 4 कक्षाएं हैं, और हमें 3 गुणों के सभी संयोजन - "बड़े", "पनीर के साथ" और "फ्राइज़ के साथ" को संभालने के लिए 4 और जोड़ना होगा। हमें अभी 8 कक्षाएं चाहिए। एक और संपत्ति जोड़ें और हमें 16 की आवश्यकता होगी। यह 2 ^ n के रूप में बढ़ेगा।
इसके बजाय, आइए एक बर्गरडाइकोरेटर को परिभाषित करने का प्रयास करें जो बर्गर ऑब्जेक्ट में लेता है:
class BurgerDecorator
def initialize(burger)
self.burger = burger
end
end
class BurgerWithCheese < BurgerDecorator
def price
self.burger.price + 15
end
end
burger = Burger.new
cheese_burger = BurgerWithCheese.new(burger)
cheese_burger.price # => 65
उपरोक्त उदाहरण में, हमने एक बर्गरडेकोरेटर वर्ग बनाया है, जिसमें से बर्गरविथेकस श्रेणी विरासत में मिली है। हम लार्जबर्गर क्लास बनाकर "बड़े" बदलाव का भी प्रतिनिधित्व कर सकते हैं। अब हम रनवे पर चीज़ के साथ एक बड़े बर्गर को परिभाषित कर सकते हैं:
b = LargeBurger.new(cheese_burger)
b.price # => 50 + 15 + 20 = 85
याद रखें कि "फ्राइज़ के साथ" विविधता को जोड़ने के लिए विरासत का उपयोग करके 4 और उपवर्गों को कैसे जोड़ा जाएगा? डेकोरेटर्स के साथ, हम नए बदलाव को संभालने और रनटाइम के दौरान इसे संभालने के लिए सिर्फ एक नया वर्ग, बर्गरविथफ्रीज बनाएंगे। प्रत्येक नई संपत्ति को सभी क्रमपरिवर्तन को कवर करने के लिए बस अधिक डेकोरेटर की आवश्यकता होगी।
पुनश्च। यह एक लेख का छोटा संस्करण है जो मैंने रूबी में डेकोरेटर पैटर्न का उपयोग करने के बारे में लिखा था , जिसे आप पढ़ सकते हैं यदि आप अधिक विस्तृत उदाहरणों का पता लगाना चाहते हैं।
डेकोरेटर:
सोर्समेकिंग का संदर्भ लें अधिक जानकारी के लिए लेख।
डेकोरेटर (सार) : यह एक सार वर्ग / इंटरफ़ेस है, जो घटक इंटरफ़ेस को लागू करता है। इसमें घटक इंटरफ़ेस है। इस वर्ग की अनुपस्थिति में, आपको विभिन्न संयोजनों के लिए कंक्रीटकॉकरेटर के कई उप-वर्गों की आवश्यकता होती है। घटक की संरचना गैर-आवश्यक उप-वर्गों को कम करती है।
JDK उदाहरण:
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File("a.txt")));
while(bis.available()>0)
{
char c = (char)bis.read();
System.out.println("Char: "+c);;
}
UML आरेख और कोड उदाहरण के लिए SE प्रश्न के नीचे एक नज़र डालें।
उपयोगी लेख:
डेकोरेटर पैटर्न का वास्तविक शब्द उदाहरण: VendingMachineDecorator @ समझाया गया है
डेकोरेटर पैटर्न का उपयोग कब करें?
Beverage beverage = new SugarDecorator(new LemonDecorator(new Tea("Assam Tea")));
beverage.decorateBeverage();
beverage = new SugarDecorator(new LemonDecorator(new Coffee("Cappuccino")));
beverage.decorateBeverage();
उपरोक्त उदाहरण में, चीनी या नींबू द्वारा चाय या कॉफी (पेय) को सजाया गया है।
डेकोरेटर पैटर्न गतिशील रूप से किसी भी वस्तु में जिम्मेदारियों को जोड़ने का एक उद्देश्य प्राप्त करता है ।
जावा I / O मॉडल डेकोरेटर पैटर्न पर आधारित है।
स्क्रॉलबार के साथ एक विंडो सजाने के बारे में विकिपीडिया पर एक उदाहरण है:
http://en.wikipedia.org/wiki/Decorator_pattern
यहाँ "टीम मेंबर, टीम लीड और मैनेजर" का एक और बहुत 'वास्तविक संसार' उदाहरण है, जो बताता है कि डेकोरेटर पैटर्न सरल विरासत के साथ अप्रतिरोध्य है:
https://zishanbilal.wordpress.com/2011/04/28/design-patterns-by-examples-decorator-pattern/
कुछ समय पहले मैंने डेकोरेटर पैटर्न का उपयोग करने के लिए एक कोडबेस को रिफलेक्ट किया था, इसलिए मैं उपयोग के मामले को समझाने की कोशिश करूंगा।
मान लें कि हमारे पास सेवाओं का एक सेट है और इस आधार पर कि उपयोगकर्ता ने विशेष सेवा का लाइसेंस प्राप्त किया है, हमें सेवा शुरू करने की आवश्यकता है।
सभी सेवाओं में एक सामान्य इंटरफ़ेस है
interface Service {
String serviceId();
void init() throws Exception;
void start() throws Exception;
void stop() throws Exception;
}
abstract class ServiceSupport implements Service {
public ServiceSupport(String serviceId, LicenseManager licenseManager) {
// assign instance variables
}
@Override
public void init() throws Exception {
if (!licenseManager.isLicenseValid(serviceId)) {
throw new Exception("License not valid for service");
}
// Service initialization logic
}
}
यदि आप ध्यान से देखते हैं, ServiceSupport
पर निर्भर है LicenseManager
। लेकिन यह निर्भर क्यों होना चाहिए LicenseManager
? क्या होगा अगर हमें पृष्ठभूमि सेवा की आवश्यकता है जो लाइसेंस जानकारी की जांच करने की आवश्यकता नहीं है। वर्तमान स्थिति में हमें किसी तरह LicenseManager
वापस लौटने के लिए प्रशिक्षित करना होगाtrue
पृष्ठभूमि सेवाओं के लिए । यह दृष्टिकोण मुझे ठीक नहीं लगा। मेरे अनुसार लाइसेंस जाँच और अन्य तर्क एक दूसरे के लिए रूढ़िवादी थे।
तो डेकोरेटर पैटर्न बचाव के लिए आता है और यहां टीडीडी के साथ रिफैक्टिंग शुरू होती है।
class LicensedService implements Service {
private Service service;
public LicensedService(LicenseManager licenseManager, Service service) {
this.service = service;
}
@Override
public void init() {
if (!licenseManager.isLicenseValid(service.serviceId())) {
throw new Exception("License is invalid for service " + service.serviceId());
}
// Delegate init to decorated service
service.init();
}
// override other methods according to requirement
}
// Not concerned with licensing any more :)
abstract class ServiceSupport implements Service {
public ServiceSupport(String serviceId) {
// assign variables
}
@Override
public void init() {
// Service initialization logic
}
}
// The services which need license protection can be decorated with a Licensed service
Service aLicensedService = new LicensedService(new Service1("Service1"), licenseManager);
// Services which don't need license can be created without one and there is no need to pass license related information
Service aBackgroundService = new BackgroundService1("BG-1");
PUBG का उदाहरण लेते हैं। असाल्ट राइफ़ल 4x ज़ूम के साथ सबसे अच्छा काम करती है और जब हम इस पर होते हैं, तो हमें कम्पेसाटर और दबानेवाला यंत्र की भी आवश्यकता होगी। यह पुनरावृत्ति को कम करेगा और फायरिंग ध्वनि के साथ-साथ गूंज को कम करेगा। हमें इस सुविधा को लागू करने की आवश्यकता होगी जहां हम खिलाड़ियों को उनकी पसंदीदा बंदूक और उनके सामान खरीदने की अनुमति देंगे। खिलाड़ी बंदूक या कुछ गौण या सभी गौण खरीद सकते हैं और उनके अनुसार शुल्क लिया जाएगा।
आइए देखें कि डेकोरेटर पैटर्न यहां कैसे लागू किया जाता है:
मान लीजिए कि कोई व्यक्ति उपरोक्त सभी तीन सामानों के साथ SCAR-L खरीदना चाहता है।
यह इस तरह एक वर्ग आरेख को जन्म देगा:
अब, हमारे पास इस तरह की कक्षाएं हो सकती हैं:
public abstract class Gun {
private Double cost;
public Double getCost() {
return cost;
}
}
public abstract class GunAccessories extends Gun { }
public class Scarl extends Gun {
public Scarl() {
cost = 100;
}
}
public class Suppressor extends GunAccessories {
Gun gun;
public Suppressor(Gun gun) {
cost = 5;
this.gun = gun;
}
public double getCost(){
return cost + gun.getCost();
}
}
public class GunShop{
public static void main(String args[]){
Gun scarl = new Scarl();
scarl = new Supressor(scarl);
System.out.println("Price is "+scarl.getCost());
}
}
हम इसी तरह अन्य सामान भी जोड़ सकते हैं और अपने गन को सजा सकते हैं।
संदर्भ:
https://nulpointerexception.com/2019/05/05/a-beginner-guide-to-decorator-pattern/
डेकोरेटर डिज़ाइन पैटर्न : यह पैटर्न रनटाइम पर किसी ऑब्जेक्ट की विशेषताओं को संशोधित करने में मदद करता है। यह किसी वस्तु को अलग-अलग स्वाद प्रदान करता है और यह चुनने के लिए लचीलापन देता है कि हम उस स्वाद में किन सामग्रियों का उपयोग करना चाहते हैं।
वास्तविक जीवन उदाहरण: आओ हम कहते हैं कि आपके पास एक उड़ान में एक मुख्य केबिन सीट है। अब आपको सीट के साथ कई सुविधाएं चुनने की अनुमति है। प्रत्येक एमेनिटी की अपनी लागत होती है। अब यदि कोई उपयोगकर्ता वाईफ़ाई और प्रीमियम भोजन चुनता है, तो उसे सीट + वाईफाई + प्रीमियम भोजन के लिए शुल्क लिया जाएगा।
इस मामले में डेकोरेटर डिजाइन पैटर्न वास्तव में हमारी मदद कर सकता है। डेकोरेटर पैटर्न और एक वास्तविक जीवन उदाहरण के कार्यान्वयन के बारे में अधिक समझने के लिए उपरोक्त लिंक पर जाएं।