← Back to Advanced Java Course | Chapter 6: Design Patterns | Lesson 8 of 14

Java का Decorator Pattern

Decorator pattern किसी object में अतिरिक्त responsibilities dynamically जोड़ता है उसे उसी interface implement करने वाले एक दूसरे object में wrap करके, subclassing का एक flexible विकल्प प्रदान करते हुए।
Syntax
java
class Decorator implements Component {
    private Component wrapped;
    public void operation() {
        wrapped.operation();
        // extra behavior
    }
}

What is the Decorator Pattern?

Decorator pattern किसी object में अतिरिक्त responsibilities dynamically जोड़ता है उसे एक दूसरे object में wrap करके जो वही interface implement करता है, behavior को extend करने के लिए subclassing का एक flexible विकल्प देते हुए।

उदाहरण: What is the Decorator Pattern?

java
public class Main {
	interface Coffee { String describe(); }
	static class SimpleCoffee implements Coffee {
		public String describe() { return "Coffee"; }
	}
	static class MilkDecorator implements Coffee {
		Coffee wrapped;
		MilkDecorator(Coffee wrapped) { this.wrapped = wrapped; }
		public String describe() { return wrapped.describe() + " + Milk"; } // wraps, same interface
	}
	public static void main(String[] args) {
		Coffee coffee = new MilkDecorator(new SimpleCoffee());
		System.out.println(coffee.describe());
	}
}

Wrapping an Object

एक decorator उसी interface को implement करता है जिसे यह wrap करता है, अपने core behavior के लिए wrapped object को delegate करते हुए और उस delegated call से पहले या बाद में अपनी खुद की logic जोड़ते हुए।

उदाहरण: Wrapping an Object

java
public class Main {
	interface Coffee { String describe(); }
	static class SimpleCoffee implements Coffee {
		public String describe() { return "Coffee"; }
	}
	static class SugarDecorator implements Coffee {
		Coffee wrapped;
		SugarDecorator(Coffee wrapped) { this.wrapped = wrapped; }
		public String describe() { return wrapped.describe() + " + Sugar"; } // delegates, then adds
	}
	public static void main(String[] args) {
		System.out.println(new SugarDecorator(new SimpleCoffee()).describe());
	}
}

Stacking Multiple Decorators

कई decorators एक-दूसरे के ऊपर किसी भी order या combination में layer किए जा सकते हैं, क्योंकि हर एक एक ही interface को implement और wrap करता है, runtime पर behavior को flexibly compose होने देते हुए।

उदाहरण: Stacking Multiple Decorators

java
public class Main {
	interface Coffee { String describe(); }
	static class SimpleCoffee implements Coffee { public String describe() { return "Coffee"; } }
	static class MilkDecorator implements Coffee {
		Coffee wrapped; MilkDecorator(Coffee wrapped) { this.wrapped = wrapped; }
		public String describe() { return wrapped.describe() + " + Milk"; }
	}
	static class SugarDecorator implements Coffee {
		Coffee wrapped; SugarDecorator(Coffee wrapped) { this.wrapped = wrapped; }
		public String describe() { return wrapped.describe() + " + Sugar"; }
	}
	public static void main(String[] args) {
		Coffee coffee = new SugarDecorator(new MilkDecorator(new SimpleCoffee())); // layered, any order
		System.out.println(coffee.describe());
	}
}

Decorator vs Inheritance

optional behavior के हर combination को जोड़ने के लिए inheritance का उपयोग करना हर combination के लिए एक नई subclass चाहता है, जल्दी ही unmanageable हो जाते हुए, जबकि decorators ज़रूरी classes की संख्या को बढ़ाए बिना स्वतंत्र रूप से combine होते हैं।

उदाहरण: Decorator vs Inheritance

java
public class Main {
	interface Coffee { String describe(); }
	static class SimpleCoffee implements Coffee { public String describe() { return "Coffee"; } }
	static class Decorator implements Coffee {
		Coffee wrapped; String extra;
		Decorator(Coffee wrapped, String extra) { this.wrapped = wrapped; this.extra = extra; }
		public String describe() { return wrapped.describe() + " + " + extra; }
	}
	public static void main(String[] args) {
		// One Decorator class combines freely, instead of MilkCoffee, SugarCoffee, MilkSugarCoffee subclasses...
		Coffee coffee = new Decorator(new Decorator(new SimpleCoffee(), "Milk"), "Sugar");
		System.out.println(coffee.describe());
	}
}

Java's Built-in Decorators

Java की अपनी I/O classes Decorator pattern का एक जाना-पहचाना असली-दुनिया उदाहरण हैं: BufferedReader, BufferedWriter, और PrintWriter सभी किसी दूसरे Reader या Writer को wrap करते हैं, उसके ऊपर buffering या formatting जोड़ते हुए।

उदाहरण: Java's Built-in Decorators

java
import java.io.*;
public class Main {
	public static void main(String[] args) throws Exception {
		StringWriter sw = new StringWriter();
		PrintWriter pw = new PrintWriter(new BufferedWriter(sw)); // both wrap and add formatting/buffering
		pw.println("wrapped output");
		pw.flush();
		System.out.println(sw.toString().trim());
	}
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. decorator के अंदर wrapped object के method को call करना भूल जाना, जिससे original behavior खो जाता है।
  2. decorator को उसके wrap किए object से अलग interface implement करवाना, जिससे यह दूसरे decorators के साथ stack नहीं हो सकता।
  3. यह नज़रअंदाज़ करना कि stacking का order मायने रखता है, जिससे अलग order में wrap करना एक अलग result देता है।

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.