Command Pattern হল একটি Behavioral Design Pattern, যা একটি অবজেক্টে একটি অনুরোধ (request) বা কমান্ড (command) encapsulate করে এবং পরে সেই কমান্ডগুলো একে একে execute করার সুযোগ দেয়। এটি নির্দেশ করে, কমান্ডের সৃষ্টিকর্তা এবং তার কার্যকরী অংশগুলির মধ্যে একটি মধ্যস্থতাকারী স্তর তৈরি করা হয়। Command Pattern ব্যবহার করে, ব্যবহারকারীরা সহজেই কমান্ডগুলো সঞ্চালন করতে পারে এবং কমান্ডগুলির কার্যকারিতা পুরো সিস্টেমে বিচ্ছিন্নভাবে কাজ করে।
এই প্যাটার্নে কমান্ডের সৃষ্টিকর্তা, এক্সিকিউটর, এবং ব্যবহারকারী সবই আলাদা হয়, যার ফলে কোডকে নমনীয় ও সঠিকভাবে রক্ষণাবেক্ষণযোগ্য করা যায়। এতে অনেক সুবিধা রয়েছে, যেমন:
- Undo/Redo Operation: এটি Undo বা Redo এর জন্য ব্যবহৃত হতে পারে, কারণ প্রতিটি কমান্ড একটি অবজেক্ট হিসেবে থাকে এবং তার ইতিহাস ট্র্যাক করা সহজ।
- Queueing of requests: এটি কমান্ডগুলিকে একটি কিউতে রেখে একে একে এক্সিকিউট করার জন্য ব্যবহৃত হতে পারে।
Command Pattern এর গঠন
Command Pattern মূলত ৩টি অংশে বিভক্ত:
- Command Interface: এটি একটি সাধারণ ইন্টারফেস যা সকল কমান্ড ক্লাসের জন্য থাকে, এবং সাধারণত execute() মেথড থাকে।
- Concrete Command: এটি Command ইন্টারফেস ইমপ্লিমেন্ট করে এবং নির্দিষ্ট Receiver (যেমন একটি অবজেক্ট) এর মাধ্যমে execute() মেথডে আদেশ সম্পাদন করে।
- Invoker: এটি সেই অবজেক্ট যা কমান্ডগুলিকে কল করে। এটি কমান্ডের একটি রেফারেন্স ধারণ করে এবং সেই কমান্ডটি কার্যকর করে।
- Receiver: এটি কমান্ডের কার্যকারিতা (যেমন কোনো অপারেশন) সম্পাদন করে।
Command Pattern এর উদাহরণ
ধরা যাক, আমাদের একটি Home Automation System রয়েছে, যেখানে বিভিন্ন কমান্ড আছে, যেমন Turn On Light, Turn Off Light, Turn On Fan, ইত্যাদি। এই কমান্ডগুলোকে একটি Invoker এর মাধ্যমে চালানো হবে এবং প্রতিটি কমান্ড Receiver কে ব্যবহার করে কার্যকর হবে।
Step-by-step উদাহরণ:
1. Command Interface:
// Command Interface
interface Command {
void execute();
}
2. Concrete Command Classes:
// Concrete Command: TurnOnLightCommand
class TurnOnLightCommand implements Command {
private Light light;
public TurnOnLightCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOn();
}
}
// Concrete Command: TurnOffLightCommand
class TurnOffLightCommand implements Command {
private Light light;
public TurnOffLightCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOff();
}
}
// Concrete Command: TurnOnFanCommand
class TurnOnFanCommand implements Command {
private Fan fan;
public TurnOnFanCommand(Fan fan) {
this.fan = fan;
}
@Override
public void execute() {
fan.turnOn();
}
}
// Concrete Command: TurnOffFanCommand
class TurnOffFanCommand implements Command {
private Fan fan;
public TurnOffFanCommand(Fan fan) {
this.fan = fan;
}
@Override
public void execute() {
fan.turnOff();
}
}
3. Receiver Classes:
// Receiver Class: Light
class Light {
public void turnOn() {
System.out.println("Light is ON");
}
public void turnOff() {
System.out.println("Light is OFF");
}
}
// Receiver Class: Fan
class Fan {
public void turnOn() {
System.out.println("Fan is ON");
}
public void turnOff() {
System.out.println("Fan is OFF");
}
}
4. Invoker Class:
// Invoker Class: RemoteControl
class RemoteControl {
private Command command;
// Set the command dynamically
public void setCommand(Command command) {
this.command = command;
}
// Invoke the command
public void pressButton() {
command.execute();
}
}
5. Client Code (Testing the Command Pattern):
public class CommandPatternDemo {
public static void main(String[] args) {
// Create receivers
Light light = new Light();
Fan fan = new Fan();
// Create concrete command objects
Command turnOnLight = new TurnOnLightCommand(light);
Command turnOffLight = new TurnOffLightCommand(light);
Command turnOnFan = new TurnOnFanCommand(fan);
Command turnOffFan = new TurnOffFanCommand(fan);
// Create invoker
RemoteControl remote = new RemoteControl();
// Simulate button presses
remote.setCommand(turnOnLight);
remote.pressButton();
remote.setCommand(turnOffLight);
remote.pressButton();
remote.setCommand(turnOnFan);
remote.pressButton();
remote.setCommand(turnOffFan);
remote.pressButton();
}
}
Output:
Light is ON
Light is OFF
Fan is ON
Fan is OFF
Command Pattern এর সুবিধা:
- Separation of Concerns: Command Pattern রিসিভার (যেমন
Light,Fan) এবং ইনভোকারের (যেমনRemoteControl) মধ্যে সম্পর্ককে আলাদা করে, ফলে সিস্টেমের পরিবর্তন এবং রক্ষণাবেক্ষণ সহজ হয়। - Undo/Redo functionality: Command Pattern সহজেই Undo বা Redo অপারেশন বাস্তবায়ন করতে সাহায্য করে, কারণ প্রত্যেকটি কমান্ড একটি অবজেক্টের মধ্যে থাকে।
- Queueing of requests: এটি কুয়েরি বা কমান্ডগুলোকে একটি কিউতে রাখা এবং তাদের পরবর্তীতে একে একে এক্সিকিউট করতে ব্যবহার করা যেতে পারে।
Command Pattern এর সীমাবদ্ধতা:
- Complexity: অনেক সময় এই প্যাটার্নটি ছোট প্রজেক্টে ব্যবহার করা হলে অতিরিক্ত জটিলতা তৈরি করতে পারে, কারণ এতে অনেক ক্লাস তৈরি হয়।
- Overhead: একাধিক কমান্ড এবং রিসিভার তৈরি করতে হলে অতিরিক্ত রিসোর্স প্রয়োজন হতে পারে।
সারাংশ
Command Pattern একটি শক্তিশালী ডিজাইন প্যাটার্ন যা কমান্ডগুলিকে একটি অবজেক্টে encapsulate করে, এবং পরে সেগুলিকে execute করার সুযোগ দেয়। এটি ব্যবহৃত হয় সফটওয়্যার সিস্টেমে যেখানে ক্লায়েন্টদের থেকে কমান্ড রিসিভ করে পরে সেগুলিকে কার্যকর করা হয়। Command Pattern সহজেই Undo/Redo, Queueing of Requests, এবং Job Scheduling এর জন্য ব্যবহার করা যায়, যা সফটওয়্যার সিস্টেমকে নমনীয় এবং সঠিকভাবে রক্ষণাবেক্ষণযোগ্য করে তোলে।
Read more