Decorator Pattern একটি স্ট্রাকচারাল ডিজাইন প্যাটার্ন, যা একটি অবজেক্টের আচরণ বা ক্ষমতাকে নতুনভাবে সাজানোর জন্য ব্যবহৃত হয়। এটি একটি ক্লাসের উপরে পরিবর্তন বা বাড়তি ফিচার যোগ করতে সক্ষম, এবং এর জন্য ক্লাসের কাঠামো পরিবর্তন না করে সেগুলিকে আড়াল করে বা প্রসারিত করে। এই প্যাটার্নটি অনেক সময় ব্যবহৃত হয় যখন কোনো ক্লাসে নতুন কার্যকারিতা যোগ করতে হয় তবে তা ঐ ক্লাসের মধ্যে সরাসরি পরিবর্তন না করে।
Decorator Pattern-এর মাধ্যমে আপনি কোনও অবজেক্টের ফাংশনালিটি সম্প্রসারিত করতে পারেন, যেটি মূল অবজেক্টকে ডিকোরেট করতে সক্ষম।
Decorator Pattern এর কাঠামো
Decorator Pattern সাধারণত তিনটি প্রধান উপাদান নিয়ে কাজ করে:
- Component: একটি সাধারণ ইন্টারফেস বা ক্লাস যা আসল বা মৌলিক আচরণ নির্ধারণ করে।
- ConcreteComponent: আসল অবজেক্ট যা Component ইন্টারফেসের ইমপ্লিমেন্টেশন।
- Decorator: Component ইন্টারফেস বা ক্লাসের উপরে একটি ডেকোরেটর ক্লাস, যা আসল ক্লাসের ফাংশনালিটি প্রসারিত বা পরিবর্তন করে।
Decorator Pattern এর উদাহরণ
ধরা যাক, আমরা একটি কার তৈরি করছি, এবং আমাদেরকে একটি সাধারণ গাড়ির উপর বিভিন্ন অতিরিক্ত ফিচার (যেমন: এসি, সনি স্পিকার, আরামদায়ক সিট) যোগ করতে হবে। এই ফিচারগুলি গাড়ির উপরে সাজানো (decorating) হবে।
1. Component Interface
প্রথমে, আমরা একটি সাধারণ Car ইন্টারফেস তৈরি করব যা সাধারণ কারের গুণাবলী নির্দেশ করবে।
public interface Car {
void assemble(); // Method to assemble the car
}
2. ConcreteComponent
এখানে আমরা একটি কনক্রিট ক্লাস তৈরি করব যা Car ইন্টারফেস ইমপ্লিমেন্ট করবে এবং একটি সাধারণ কারের বৈশিষ্ট্য নির্দেশ করবে।
public class BasicCar implements Car {
@Override
public void assemble() {
System.out.println("Basic Car.");
}
}
3. Decorator Class
এখন আমরা একটি Decorator ক্লাস তৈরি করব, যা Car ইন্টারফেসে নির্দিষ্ট ফিচার যোগ করতে সক্ষম হবে।
public class CarDecorator implements Car {
protected Car decoratedCar; // A reference to the decorated car
public CarDecorator(Car car) {
this.decoratedCar = car;
}
@Override
public void assemble() {
this.decoratedCar.assemble(); // Delegates the call to the decorated car
}
}
4. Concrete Decorators
এখন আমরা বিভিন্ন কনক্রিট ডেকোরেটর তৈরি করব যা CarDecorator থেকে ইনহেরিট করবে এবং গাড়ির উপর নতুন ফিচার যোগ করবে।
public class SportsCar extends CarDecorator {
public SportsCar(Car car) {
super(car);
}
@Override
public void assemble() {
super.assemble();
System.out.println("Adding features of Sports Car.");
}
}
public class LuxuryCar extends CarDecorator {
public LuxuryCar(Car car) {
super(car);
}
@Override
public void assemble() {
super.assemble();
System.out.println("Adding features of Luxury Car.");
}
}
5. Testing the Decorator Pattern
এখন আমরা ডেকোরেটর প্যাটার্নের ব্যবহার দেখব যেখানে প্রথমে একটি সাধারণ গাড়ি তৈরি করা হবে এবং তারপর তা বিভিন্ন ফিচার দিয়ে সাজানো হবে।
public class DecoratorPatternExample {
public static void main(String[] args) {
// Create a basic car
Car sportsCar = new SportsCar(new BasicCar());
sportsCar.assemble(); // Output: Basic Car. Adding features of Sports Car.
// Create a luxury car
Car sportsLuxuryCar = new SportsCar(new LuxuryCar(new BasicCar()));
sportsLuxuryCar.assemble();
// Output: Basic Car. Adding features of Luxury Car. Adding features of Sports Car.
}
}
আউটপুট:
Basic Car.
Adding features of Sports Car.
Basic Car.
Adding features of Luxury Car.
Adding features of Sports Car.
Decorator Pattern এর ব্যাখ্যা:
- BasicCar: এটি একটি সাধারণ গাড়ি, যা
assemble()মেথডের মাধ্যমে একটি সাধারণ গাড়ি তৈরি করবে। - SportsCar এবং LuxuryCar: এই দুটি ক্লাস
CarDecoratorইন্টারফেস ইমপ্লিমেন্ট করে এবং একটি সাধারণ গাড়িতে অতিরিক্ত ফিচার যোগ করে। - Decorator Pattern: ডেকোরেটর প্যাটার্নের মাধ্যমে আমরা একাধিক ফিচার একসাথে যুক্ত করতে পারি, যেমন
SportsCarএবংLuxuryCarএকসাথে যোগ করা যেতে পারে। এতে করে নতুন ফিচার যোগ করার জন্য পূর্ববর্তী ক্লাসে পরিবর্তন না করে আমরা অবজেক্টের ফাংশনালিটি প্রসারিত করতে পারি।
Advantages of Decorator Pattern:
- Flexible: ডেকোরেটর প্যাটার্নের মাধ্যমে আমরা সহজেই নতুন ফিচার যুক্ত করতে পারি। এটি কার্যকরীভাবে ফিচার পরিবর্তন বা সম্প্রসারণ করতে সাহায্য করে।
- Avoids subclassing: নতুন ফিচার যোগ করার জন্য নতুন সাবক্লাস তৈরি করার প্রয়োজন নেই। ডেকোরেটর ক্লাস দ্বারা বৈশিষ্ট্য যোগ করা যেতে পারে।
- Open/Closed Principle: ডেকোরেটর প্যাটার্ন open/closed principle অনুসরণ করে, অর্থাৎ ক্লাসটি নতুন ফিচারের জন্য উন্মুক্ত, তবে বিদ্যমান কোডে পরিবর্তন না করে তা সম্প্রসারিত করা যায়।
Decorator Pattern একটি শক্তিশালী ডিজাইন প্যাটার্ন যা অবজেক্টের আচরণ বা ফিচারকে ডায়নামিকভাবে এবং নমনীয়ভাবে পরিবর্তন করতে সক্ষম। এটি বিশেষত তখন উপকারী যখন একটি ক্লাসের মৌলিক কার্যকারিতার উপর নতুন ফিচার যোগ করা প্রয়োজন, কিন্তু মূল কোড বা ক্লাসের কাঠামো পরিবর্তন করা সম্ভব নয় বা প্রয়োজন নেই। ডেকোরেটর প্যাটার্ন সাধারণত UI ডিজাইন, লগিং, এবং একাধিক ধরণের কনফিগারেশনে ব্যবহৃত হয়, যেখানে প্রতিটি অবজেক্টের উপর কার্যকারিতা যুক্ত করা হয় বিভিন্ন উপায়ে।