Observer Pattern এবং Decorator Pattern হল দুটি জনপ্রিয় ডিজাইন প্যাটার্ন যা সফটওয়্যার ডিজাইন এবং উন্নয়নে ব্যাপকভাবে ব্যবহৃত হয়। প্রতিটি প্যাটার্নের নিজস্ব উদ্দেশ্য এবং ব্যবহারিক ক্ষেত্র রয়েছে। চলুন, আমরা প্রতিটি প্যাটার্নের ব্যাখ্যা এবং উদাহরণ সহ বিস্তারিত আলোচনা করি।
1. Observer Pattern:
Observer Pattern হল একটি behavioral design pattern যা একটি subject এর পরিবর্তন সম্পর্কে observers (অথবা listeners) কে অবহিত (notify) করতে ব্যবহৃত হয়। এটি একে একে বিভিন্ন ক্লাসকে একটি নির্দিষ্ট সাবজেক্টের পরিবর্তনের বিষয়ে অবগত করে রাখে। এই প্যাটার্নটি সাধারণত event handling সিস্টেমে, model-view-controller (MVC) আর্কিটেকচারে এবং notification systems-এ ব্যবহৃত হয়।
ব্যাখ্যা:
- Subject (Observable): এটি একটি কন্ট্রোল অবজেক্ট যা অন্য অবজেক্টগুলিকে (Observers) তাদের স্টেট পরিবর্তনের বিষয়ে জানায়।
- Observer: এটি এক বা একাধিক অবজেক্ট যা কোনও সাবজেক্টের পরিবর্তন পর্যবেক্ষণ করে এবং অবহিত হয়।
এটি ব্যবহার করা হয় যেখানে একাধিক অবজেক্টকে আপডেট বা নোটিফাই করা প্রয়োজন যখন একটি নির্দিষ্ট অবজেক্টের অবস্থান পরিবর্তিত হয়।
Observer Pattern উদাহরণ:
import java.util.ArrayList;
import java.util.List;
// Observer interface
interface Observer {
void update(String message);
}
// Concrete Observer
class ConcreteObserver implements Observer {
private String name;
public ConcreteObserver(String name) {
this.name = name;
}
@Override
public void update(String message) {
System.out.println(name + " received message: " + message);
}
}
// Subject (Observable)
class Subject {
private List<Observer> observers = new ArrayList<>();
// Add an observer
public void addObserver(Observer observer) {
observers.add(observer);
}
// Remove an observer
public void removeObserver(Observer observer) {
observers.remove(observer);
}
// Notify all observers
public void notifyObservers(String message) {
for (Observer observer : observers) {
observer.update(message);
}
}
}
// Main class
public class ObserverPatternExample {
public static void main(String[] args) {
// Create subject
Subject subject = new Subject();
// Create observers
Observer observer1 = new ConcreteObserver("Observer 1");
Observer observer2 = new ConcreteObserver("Observer 2");
// Register observers with the subject
subject.addObserver(observer1);
subject.addObserver(observer2);
// Notify observers
subject.notifyObservers("Hello Observers!");
}
}
Output:
Observer 1 received message: Hello Observers!
Observer 2 received message: Hello Observers!
ব্যাখ্যা:
- Subject একটি সেন্ট্রাল ক্লাস যা ConcreteObserver এর মতো observers রাখে।
- যখন subject.notifyObservers("Hello Observers!") কল করা হয়, তখন সব observer গুলি update() মেথডের মাধ্যমে পরিবর্তন সম্পর্কে অবহিত হয়।
2. Decorator Pattern:
Decorator Pattern হল একটি structural design pattern যা একটি অবজেক্টের functionality বা behavior এর উপর dynamically নতুন বৈশিষ্ট্য যোগ করতে ব্যবহৃত হয়। এটি inheritance এর পরিবর্তে composition ব্যবহার করে, যা object-oriented programming এ flexibility বৃদ্ধি করে। এটি মূলত object composition এর মাধ্যমে কাজ করে, যেখানে আপনি মূল object এর behavior বা functionality পরিবর্তন না করে নতুন functionality যোগ করতে পারেন।
ব্যাখ্যা:
- Component: এটি একটি সাধারণ interface বা abstract class যা মৌলিক ফাংশনালিটি নির্ধারণ করে।
- ConcreteComponent: এটি Component এর বাস্তবায়ন যা মৌলিক ফাংশনালিটি প্রদান করে।
- Decorator: এটি Component এর একটি subclass বা implementation যা মৌলিক component এর behavior কে পরিবর্তন বা প্রসারিত করতে সহায়ক।
- ConcreteDecorator: এটি Decorator এর বাস্তবায়ন যা নতুন ফাংশনালিটি যোগ করে।
Decorator Pattern উদাহরণ:
// Component Interface
interface Coffee {
double cost();
}
// Concrete Component
class SimpleCoffee implements Coffee {
@Override
public double cost() {
return 5.0; // basic coffee cost
}
}
// Decorator Class
abstract class CoffeeDecorator implements Coffee {
protected Coffee decoratedCoffee;
public CoffeeDecorator(Coffee coffee) {
this.decoratedCoffee = coffee;
}
public double cost() {
return decoratedCoffee.cost();
}
}
// Concrete Decorators
class MilkDecorator extends CoffeeDecorator {
public MilkDecorator(Coffee coffee) {
super(coffee);
}
@Override
public double cost() {
return decoratedCoffee.cost() + 2.0; // adds cost for milk
}
}
class SugarDecorator extends CoffeeDecorator {
public SugarDecorator(Coffee coffee) {
super(coffee);
}
@Override
public double cost() {
return decoratedCoffee.cost() + 1.5; // adds cost for sugar
}
}
// Main class
public class DecoratorPatternExample {
public static void main(String[] args) {
Coffee coffee = new SimpleCoffee();
System.out.println("Cost of Simple Coffee: " + coffee.cost());
// Adding Milk
coffee = new MilkDecorator(coffee);
System.out.println("Cost of Coffee with Milk: " + coffee.cost());
// Adding Sugar
coffee = new SugarDecorator(coffee);
System.out.println("Cost of Coffee with Milk and Sugar: " + coffee.cost());
}
}
Output:
Cost of Simple Coffee: 5.0
Cost of Coffee with Milk: 7.0
Cost of Coffee with Milk and Sugar: 8.5
ব্যাখ্যা:
- SimpleCoffee হল ConcreteComponent, যা শুধুমাত্র একটি সাধারণ কফি তৈরি করে।
- MilkDecorator এবং SugarDecorator হল ConcreteDecorators, যা যথাক্রমে দুধ এবং চিনি যোগ করে কফির খরচ বাড়ায়।
- CoffeeDecorator হল একটি অ্যাবস্ট্রাক্ট ডেকোরেটর ক্লাস যা মৌলিক কফির behavior পরিবর্তন বা প্রসারিত করতে ব্যবহৃত হয়।
পার্থক্য Observer এবং Decorator Pattern এর মধ্যে:
| বৈশিষ্ট্য | Observer Pattern | Decorator Pattern |
|---|---|---|
| প্রকার | Behavioral Design Pattern | Structural Design Pattern |
| উদ্দেশ্য | একাধিক observer কে subject এর পরিবর্তন সম্পর্কে অবহিত করা। | একটি অবজেক্টের functionality পরিবর্তন/প্রসারিত করা। |
| ব্যবহার | Event handling, Notification systems, MVC design | Dynamic behavior addition to objects without modifying the original object. |
| প্রধান উপাদান | Subject, Observer, ConcreteObserver | Component, ConcreteComponent, Decorator, ConcreteDecorator |
| প্রতিক্রিয়া | একাধিক observers একই subject এর পরিবর্তন সম্পর্কে জানায়। | মৌলিক অবজেক্টের behavior প্রসারিত হয়। |
- Observer Pattern এমন একটি প্যাটার্ন যা একাধিক অবজেক্টকে আপডেট বা নোটিফাই করার জন্য ব্যবহার করা হয়, যখন একটি নির্দিষ্ট অবজেক্টের অবস্থান পরিবর্তিত হয়।
- Decorator Pattern এমন একটি প্যাটার্ন যা object composition এর মাধ্যমে একাধিক behavior বা functionality নতুনভাবে যোগ করার সুযোগ দেয়, যা inheritance এর পরিবর্তে আরও নমনীয় এবং reusable।
এই দুটি প্যাটার্ন সফটওয়্যার ডিজাইনের জন্য অত্যন্ত গুরুত্বপূর্ণ এবং তাদের ব্যবহারের ক্ষেত্র একে অপরের থেকে আলাদা হলেও, তারা একটি কার্যকরী এবং নমনীয় সফটওয়্যার সিস্টেম তৈরি করতে সাহায্য করে।
Read more