Design Patterns হল কিছু অভিজ্ঞ ডেভেলপারদের দ্বারা সুপারিশকৃত সমাধান পদ্ধতি, যা সফটওয়্যার ডিজাইনে পুনরায় ব্যবহৃত হতে পারে। এগুলি সাধারণত object-oriented design এর সমস্যাগুলির সমাধানে ব্যবহৃত হয়। ডিজাইন প্যাটার্নগুলি সফটওয়্যার প্রকল্পের maintainability, scalability, এবং flexibility বাড়াতে সাহায্য করে।
এই টিউটোরিয়ালে আমরা Java তে কয়েকটি সাধারণ ডিজাইন প্যাটার্ন এবং তাদের বাস্তবায়ন দেখব।
1. Creational Design Patterns
Creational Patterns হল ডিজাইন প্যাটার্নের একটি ক্যাটাগরি যা অবজেক্ট তৈরি করার প্রক্রিয়াকে নিয়ন্ত্রণ করে, যাতে কোডে flexibility এবং reuse নিশ্চিত করা যায়। সাধারণত এই প্যাটার্নগুলো একটি ক্লাসের ইনস্ট্যান্স তৈরি করার সময় বিভিন্ন কৌশল ব্যবহার করে।
1.1 Singleton Pattern
Singleton Pattern এমন একটি প্যাটার্ন যা নিশ্চিত করে যে কোনো ক্লাসের শুধুমাত্র একটি ইনস্ট্যান্স তৈরি হবে এবং সেই ইনস্ট্যান্সটি সার্বভৌমভাবে অ্যাক্সেসযোগ্য থাকবে।
বাস্তবায়ন: Singleton Pattern
public class Singleton {
private static Singleton instance;
// Private constructor to prevent instantiation
private Singleton() {}
// Method to provide the global point of access
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
public class SingletonExample {
public static void main(String[] args) {
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
System.out.println(s1 == s2); // true
}
}
ব্যাখ্যা:
- Singleton class:
getInstance()মেথড নিশ্চিত করে যে শুধুমাত্র একটি ইনস্ট্যান্স তৈরি হবে এবং তা রিটার্ন করবে। - Private constructor: এটি বাইরের ক্লাস থেকে ইন্সট্যান্স তৈরি হতে বাধা দেয়।
2. Structural Design Patterns
Structural Patterns এই প্যাটার্নগুলির কাজ হল সফটওয়্যার সিস্টেমে অবজেক্ট এবং ক্লাসের মধ্যে সম্পর্ক তৈরি করা, যাতে কাঠামোটি আরও মডুলার এবং পুনঃব্যবহারযোগ্য হয়।
2.1 Adapter Pattern
Adapter Pattern এমন একটি প্যাটার্ন যা একটি ক্লাসের ইন্টারফেসকে অন্য একটি ক্লাসের ইন্টারফেসে রূপান্তরিত করে, যাতে দুটি অমিল ইন্টারফেস একে অপরের সাথে কাজ করতে পারে।
বাস্তবায়ন: Adapter Pattern
interface MediaPlayer {
void play(String audioType, String fileName);
}
class AudioPlayer implements MediaPlayer {
@Override
public void play(String audioType, String fileName) {
if (audioType.equalsIgnoreCase("mp3")) {
System.out.println("Playing MP3 file: " + fileName);
} else {
System.out.println("Invalid media type");
}
}
}
interface AdvancedMediaPlayer {
void playVlc(String fileName);
void playMp4(String fileName);
}
class VlcPlayer implements AdvancedMediaPlayer {
@Override
public void playVlc(String fileName) {
System.out.println("Playing VLC file: " + fileName);
}
@Override
public void playMp4(String fileName) {}
}
class Mp4Player implements AdvancedMediaPlayer {
@Override
public void playVlc(String fileName) {}
@Override
public void playMp4(String fileName) {
System.out.println("Playing MP4 file: " + fileName);
}
}
class MediaAdapter implements MediaPlayer {
AdvancedMediaPlayer advancedMusicPlayer;
public MediaAdapter(String audioType) {
if (audioType.equalsIgnoreCase("vlc")) {
advancedMusicPlayer = new VlcPlayer();
} else if (audioType.equalsIgnoreCase("mp4")) {
advancedMusicPlayer = new Mp4Player();
}
}
@Override
public void play(String audioType, String fileName) {
if (audioType.equalsIgnoreCase("vlc")) {
advancedMusicPlayer.playVlc(fileName);
} else if (audioType.equalsIgnoreCase("mp4")) {
advancedMusicPlayer.playMp4(fileName);
}
}
}
public class AdapterPatternExample {
public static void main(String[] args) {
AudioPlayer audioPlayer = new AudioPlayer();
audioPlayer.play("mp3", "beyond the horizon.mp3");
audioPlayer.play("mp4", "alone.mp4");
MediaAdapter mediaAdapter = new MediaAdapter("vlc");
mediaAdapter.play("vlc", "mind me.vlc");
}
}
ব্যাখ্যা:
- MediaAdapter class: এটি
MediaPlayerইন্টারফেসের সাথে কাজ করে এবং AdvancedMediaPlayer ইন্টারফেসকে অ্যাডাপ্ট করে, যেমনVlcPlayerএবংMp4Player।
3. Behavioral Design Patterns
Behavioral Patterns কোডের বিভিন্ন অবজেক্টের মধ্যে interaction এবং communication এর কাঠামো নির্ধারণ করে।
3.1 Observer Pattern
Observer Pattern হল একটি আচরণগত প্যাটার্ন যা one-to-many সম্পর্ক স্থাপন করে, যেখানে একেকটি অবজেক্টের স্টেট পরিবর্তিত হলে, একাধিক অবজেক্ট তা অবহিত হয় (notify)।
বাস্তবায়ন: Observer Pattern
import java.util.*;
interface Observer {
void update(String message);
}
class ConcreteObserver implements Observer {
private String observerName;
public ConcreteObserver(String name) {
this.observerName = name;
}
@Override
public void update(String message) {
System.out.println(observerName + " received message: " + message);
}
}
interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>();
private String state;
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(state);
}
}
public void setState(String state) {
this.state = state;
notifyObservers();
}
}
public class ObserverPatternExample {
public static void main(String[] args) {
ConcreteSubject subject = new ConcreteSubject();
ConcreteObserver observer1 = new ConcreteObserver("Observer 1");
ConcreteObserver observer2 = new ConcreteObserver("Observer 2");
subject.registerObserver(observer1);
subject.registerObserver(observer2);
subject.setState("New State!");
}
}
ব্যাখ্যা:
- ConcreteSubject: অবজেক্টের স্টেট পরিবর্তন হলে, এটি সমস্ত রেজিস্টারড Observers কে অবহিত করে।
- Observer ইন্টারফেসের মাধ্যমে, একাধিক অবজেক্ট স্টেট পরিবর্তন অনুসরণ করে (observe)।
4. Summary
Java Design Patterns সফটওয়্যার ডিজাইন ও উন্নয়ন প্রক্রিয়াকে আরও কার্যকরী, মডুলার এবং রক্ষণাবেক্ষণযোগ্য করতে সহায়তা করে। আমরা এখানে কয়েকটি সাধারণ ডিজাইন প্যাটার্নের বাস্তবায়ন দেখেছি:
- Creational Patterns:
- Singleton Pattern: শুধুমাত্র একটি ইনস্ট্যান্স তৈরি নিশ্চিত করা।
- Structural Patterns:
- Adapter Pattern: দুটি অমিল ইন্টারফেসকে একে অপরের সাথে কাজ করতে সক্ষম করা।
- Behavioral Patterns:
- Observer Pattern: একাধিক অবজেক্টের মাঝে স্টেট পরিবর্তন সম্পর্কে অবহিত করা।
এই ডিজাইন প্যাটার্নগুলি সফটওয়্যার ডেভেলপমেন্টে পুনঃব্যবহারযোগ্য এবং স্কেলেবেল সলিউশন প্রদান করে, যা কোডের রক্ষণাবেক্ষণ সহজ করে তোলে।
Read more