खोज…


परिचय

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

यह पैटर्न एक डेकोरेटर वर्ग बनाता है जो मूल वर्ग को लपेटता है और कक्षा के तरीकों के हस्ताक्षर को बरकरार रखते हुए अतिरिक्त कार्यक्षमता प्रदान करता है।

पैरामीटर

पैरामीटर विवरण
पेय पदार्थ यह चाय या कॉफी हो सकती है

VendingMachineDecorator

विकीपीडिया के अनुसार डेकोरेटर की परिभाषा:

डेकोरेटर पैटर्न का उपयोग किसी वस्तु की कार्यक्षमता को वैधानिक रूप से बढ़ाने (सजाने) के लिए, या रन-टाइम में कुछ मामलों में, एक ही वर्ग के अन्य उदाहरणों से स्वतंत्र रूप से किया जा सकता है, बशर्ते कुछ ग्राउंडवर्क डिज़ाइन समय पर किए गए हों।

डेकोरेटर गतिशील रूप से किसी वस्तु को अतिरिक्त जिम्मेदारियां देता है। डेकोरेटर्स कार्यक्षमता बढ़ाने के लिए उपवर्ग के लिए एक लचीला विकल्प प्रदान करते हैं।

डेकोरेटर पैटर्न में चार घटक होते हैं।

यहाँ छवि विवरण दर्ज करें

  1. घटक इंटरफ़ेस: यह विशेष कार्यों को निष्पादित करने के लिए एक इंटरफ़ेस को परिभाषित करता है
  2. कंक्रीटकम्पोनेंट: यह घटक इंटरफ़ेस में परिभाषित संचालन को लागू करता है
  3. डेकोरेटर (सार): यह एक सार वर्ग है, जो घटक इंटरफ़ेस का विस्तार करता है। इसमें घटक इंटरफ़ेस है। इस वर्ग की अनुपस्थिति में, आपको विभिन्न संयोजनों के लिए कंक्रीटकॉकरर्स के कई उप-वर्गों की आवश्यकता होती है। घटक की संरचना गैर-आवश्यक उप-वर्गों को कम करती है।
  4. कंक्रीटडेकोरेटर: यह सार डेकोरेटर का कार्यान्वयन करता है।

उदाहरण कोड पर वापस आ रहा है,

  1. पेय घटक है। यह एक अमूर्त विधि को परिभाषित करता है: सजावट
  2. चाय और कॉफी पेय के ठोस कार्यान्वयन हैं।
  3. बेवरडेकोरेटर एक अमूर्त वर्ग है, जिसमें पेय पदार्थ होता है
  4. SugarDecorator और LemonDecorator पेयडैक्टर के लिए ठोस सज्जाकार हैं।

EDIT: एक या एक से अधिक फ्लेवर जैसे कि चीनी, नींबू आदि (फ्लेवर्स डेकोरेटर) को जोड़कर पेय की कीमत के वास्तविक विश्व परिदृश्य को प्रतिबिंबित करने के लिए उदाहरण को बदला गया।

abstract class Beverage {
    protected String name;
    protected int price;
    public Beverage(){
        
    }
    public  Beverage(String name){
        this.name = name;
    }
    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
    protected void setPrice(int price){
        this.price = price;
    }
    protected int getPrice(){
        return price;
    }
    protected abstract void decorateBeverage();
    
}
class Tea extends Beverage{
    public Tea(String name){
        super(name);
        setPrice(10);
    }
    public void decorateBeverage(){
        System.out.println("Cost of:"+ name +":"+ price);
        // You can add some more functionality
    }
}
class Coffee extends Beverage{
    public Coffee(String name){
        super(name);
        setPrice(15);
    }
    public void decorateBeverage(){
        System.out.println("Cost of:"+ name +":"+ price);
        // You can add some more functionality
    }    
}
abstract class BeverageDecorator extends Beverage {
    protected Beverage beverage;
    public BeverageDecorator(Beverage beverage){    
        this.beverage = beverage;    
        setName(beverage.getName()+"+"+getDecoratedName());
        setPrice(beverage.getPrice()+getIncrementPrice());
    }
    public void decorateBeverage(){
        beverage.decorateBeverage();
        System.out.println("Cost of:"+getName()+":"+getPrice());
    }    
    public abstract int getIncrementPrice();
    public abstract String getDecoratedName();
}
class SugarDecorator extends BeverageDecorator{
    public SugarDecorator(Beverage beverage){
        super(beverage);
    }
    public void decorateBeverage(){
        super.decorateBeverage();
        decorateSugar();        
    }
    public void decorateSugar(){
        System.out.println("Added Sugar to:"+beverage.getName());
    }
    public int getIncrementPrice(){
        return 5;
    }
    public String getDecoratedName(){
        return "Sugar";
    }
}
class LemonDecorator extends BeverageDecorator{
    public LemonDecorator(Beverage beverage){
        super(beverage);
    }
    public void decorateBeverage(){
        super.decorateBeverage();
        decorateLemon();    
    }
    public void decorateLemon(){
        System.out.println("Added Lemon to:"+beverage.getName());        
    }
    public int getIncrementPrice(){
        return 3;
    }
    public String getDecoratedName(){
        return "Lemon";
    }
}

public class VendingMachineDecorator {    
    public static void main(String args[]){
        Beverage beverage = new SugarDecorator(new LemonDecorator(new Tea("Assam Tea")));
        beverage.decorateBeverage();
        beverage = new SugarDecorator(new LemonDecorator(new Coffee("Cappuccino")));
        beverage.decorateBeverage();
    }
}

उत्पादन:

Cost of:Assam Tea:10
Cost of:Assam Tea+Lemon:13
Added Lemon to:Assam Tea
Cost of:Assam Tea+Lemon+Sugar:18
Added Sugar to:Assam Tea+Lemon
Cost of:Cappuccino:15
Cost of:Cappuccino+Lemon:18
Added Lemon to:Cappuccino
Cost of:Cappuccino+Lemon+Sugar:23
Added Sugar to:Cappuccino+Lemon

यह उदाहरण पेय में कई स्वाद जोड़ने के बाद वेंडिंग मशीन में पेय की लागत की गणना करता है।

उपरोक्त उदाहरण में:

चाय की लागत = 10, नींबू = 3 और चीनी = 5. यदि आप चीनी + नींबू + चाय बनाते हैं, तो इसकी लागत 18 है।

कॉफ़ी = 15 की लागत, नींबू = 3 और चीनी = 5. यदि आप चीनी + नींबू + कॉफी बनाते हैं, तो इसकी कीमत 23 है

दोनों पेय (चाय और कॉफी) के लिए एक ही डेकोरेटर का उपयोग करके, उप-वर्गों की संख्या कम कर दी गई है। डेकोरेटर पैटर्न की अनुपस्थिति में, आपके पास विभिन्न संयोजनों के लिए अलग-अलग उप कक्षाएं होनी चाहिए।

संयोजन इस प्रकार होगा:

SugarLemonTea
SugarTea
LemonTea

SugarLemonCapaccuino
SugarCapaccuino
LemonCapaccuino

आदि।

दोनों पेय पदार्थों के लिए एक ही Decorator का उपयोग करके, उप-वर्गों की संख्या कम कर दी गई है। इस पैटर्न में उपयोग की जाने वाली inheritance अवधारणा के बजाय composition कारण यह संभव है।

अन्य डिजाइन पैटर्न के साथ तुलना ( स्रोत लेख से)

  1. एडेप्टर अपने विषय के लिए एक अलग इंटरफ़ेस प्रदान करता है। प्रॉक्सी समान इंटरफ़ेस प्रदान करता है। डेकोरेटर एक बढ़ाया इंटरफ़ेस प्रदान करता है।

  2. एडॉप्टर एक ऑब्जेक्ट का इंटरफ़ेस बदलता है, डेकोरेटर एक ऑब्जेक्ट की जिम्मेदारियों को बढ़ाता है।

  3. कंपोजिट और डेकोरेटर में समान संरचना आरेख है, इस तथ्य को दर्शाती है कि दोनों पुनरावर्ती रचना पर निर्भर करते हैं ताकि वस्तुओं की खुले सिरे की संख्या को व्यवस्थित किया जा सके

  4. डेकोरेटर को उप -वर्ग के बिना वस्तुओं में जिम्मेदारियों को जोड़ने के लिए डिज़ाइन किया गया है। समग्र का ध्यान न केवल अलंकरण पर है बल्कि प्रतिनिधित्व पर है

  5. डेकोरेटर और प्रॉक्सी के अलग-अलग उद्देश्य हैं लेकिन समान संरचनाएं हैं

  6. डेकोरेटर आपको किसी वस्तु की त्वचा को बदलने देता है। रणनीति आपको हिम्मत बदलने की सुविधा देती है।

मुख्य उपयोग के मामले:

  1. अतिरिक्त कार्यात्मकता / जिम्मेदारियों को गतिशील रूप से जोड़ें
  2. कार्यात्मकताओं / जिम्मेदारियों को गतिशील रूप से निकालें
  3. अतिरिक्त जिम्मेदारियों को जोड़ने के लिए बहुत अधिक उप-वर्गीकरण से बचें।

कैशिंग डेकोरेटर

यह उदाहरण प्रदर्शित करता है कि DbProductRepository पैटर्न का उपयोग करके DbProductRepository कैशिंग क्षमताओं को कैसे जोड़ा DbProductRepository । यह दृष्टिकोण SOLID सिद्धांतों का पालन करता है क्योंकि यह आपको एकल जिम्मेदारी सिद्धांत या ओपन / बंद सिद्धांत का उल्लंघन किए बिना कैशिंग जोड़ने की अनुमति देता है।

public interface IProductRepository
{
    Product GetProduct(int id);
}

public class DbProductRepository : IProductRepository
{
    public Product GetProduct(int id)
    {
        //return Product retrieved from DB
    }
}

public class ProductRepositoryCachingDecorator : IProductRepository
{
    private readonly IProductRepository _decoratedRepository;
    private readonly ICache _cache;
    private const int ExpirationInHours = 1;

    public ProductRepositoryCachingDecorator(IProductRepository decoratedRepository, ICache cache)
    {
        _decoratedRepository = decoratedRepository;
        _cache = cache;
    }

    public Product GetProduct(int id)
    {
        var cacheKey = GetKey(id);
        var product = _cache.Get<Product>(cacheKey);
        if (product == null)
        {
            product = _decoratedRepository.GetProduct(id);
            _cache.Set(cacheKey, product, DateTimeOffset.Now.AddHours(ExpirationInHours));
        }
        
        return product;
    }

    private string GetKey(int id) => "Product:" + id.ToString();
}

public interface ICache
{
    T Get<T>(string key);
    void Set(string key, object value, DateTimeOffset expirationTime)
}

उपयोग:

var productRepository = new ProductRepositoryCachingDecorator(new DbProductRepository(), new Cache());
var product = productRepository.GetProduct(1);

GetProduct को लागू करने का परिणाम होगा: कैश (डेकोरेटर जिम्मेदारी) से उत्पाद को पुनः प्राप्त करें, यदि उत्पाद DbProductRepository लिए मंगलाचरण के साथ कैश में नहीं था और DB से उत्पाद प्राप्त करता है। इस उत्पाद को कैश में जोड़ा जा सकता है, इसलिए बाद की कॉल डीबी को हिट नहीं करेगी।



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow