Java 8 এ Lambda Expressions এবং Streams API যেমন নতুন বৈশিষ্ট্যগুলি পরিচয় করানো হয়েছে, তা অনেক ডিজাইন প্যাটার্নকে আরও কার্যকরী এবং কমপ্লেক্সিটি কম করে বাস্তবায়ন করতে সাহায্য করে। Lambda expressions এবং Streams Java কোডের আরও ছোট, পরিষ্কার এবং দক্ষ সমাধান প্রদান করে, যা কিছু পুরনো ডিজাইন প্যাটার্ন যেমন Strategy Pattern, Observer Pattern, এবং Command Pattern সহজভাবে বাস্তবায়ন করতে সক্ষম।
এই বিভাগে, আমরা দেখব কীভাবে Java 8 এর Lambda Expressions এবং Streams ব্যবহার করে কিছু জনপ্রিয় Design Patterns এর বাস্তবায়ন করা যায়।
1. Strategy Pattern with Java 8 Lambda
Strategy Pattern একটি Behavioral Design Pattern যা আলাদা আলাদা কৌশল (strategy) ধারণ করে এবং প্রয়োজনে সেগুলি পরিবর্তন করতে দেয়। Java 8 এর Lambda Expressions ব্যবহার করে আপনি এই কৌশলটি আরও সহজে বাস্তবায়ন করতে পারেন।
Traditional Strategy Pattern Example:
interface PaymentStrategy {
void pay(int amount);
}
class CreditCardPayment implements PaymentStrategy {
public void pay(int amount) {
System.out.println("Paid " + amount + " using Credit Card");
}
}
class PayPalPayment implements PaymentStrategy {
public void pay(int amount) {
System.out.println("Paid " + amount + " using PayPal");
}
}
class PaymentContext {
private PaymentStrategy strategy;
public PaymentContext(PaymentStrategy strategy) {
this.strategy = strategy;
}
public void executePayment(int amount) {
strategy.pay(amount);
}
}
Lambda Based Strategy Pattern Example:
import java.util.function.IntConsumer;
public class StrategyPatternLambda {
public static void main(String[] args) {
// Using Lambda for Payment Strategy
IntConsumer creditCardPayment = amount -> System.out.println("Paid " + amount + " using Credit Card");
IntConsumer paypalPayment = amount -> System.out.println("Paid " + amount + " using PayPal");
// Strategy Context with Lambda Expressions
PaymentContext context1 = new PaymentContext(creditCardPayment);
PaymentContext context2 = new PaymentContext(paypalPayment);
context1.executePayment(1000); // Credit Card Payment
context2.executePayment(1500); // PayPal Payment
}
}
ব্যাখ্যা:
- এখানে,
PaymentStrategyইন্টারফেসটি একটি Lambda Expression দিয়ে সরলীকৃত হয়েছে, যার মাধ্যমে pay() মেথডের লজিক সরাসরি ইনলাইন করা হয়েছে। IntConsumerব্যবহার করে আমরা পেমেন্ট স্ট্র্যাটেজি তৈরি করেছি, যেগুলি কনস্ট্রাক্টর মাধ্যমে PaymentContext-এ পাস করা হয় এবং প্রয়োগ করা হয়।
2. Observer Pattern with Java 8 Streams
Observer Pattern একটি Behavioral Design Pattern যা অবজার্ভার এবং সাবজেক্টের মধ্যে যোগাযোগ সিস্টেম তৈরি করে, যেখানে একাধিক অবজার্ভার এক্সেস পায় কোনও পরিবর্তন ঘটলেই। Java 8 এর Streams API ব্যবহার করে আমরা এই প্যাটার্নটি সহজেই বাস্তবায়ন করতে পারি।
Traditional Observer Pattern Example:
import java.util.ArrayList;
import java.util.List;
interface Observer {
void update(String message);
}
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);
}
}
class Subject {
private List<Observer> observers = new ArrayList<>();
public void addObserver(Observer observer) {
observers.add(observer);
}
public void notifyObservers(String message) {
for (Observer observer : observers) {
observer.update(message);
}
}
}
Streams-based Observer Pattern Example:
import java.util.*;
import java.util.stream.Stream;
interface Observer {
void update(String message);
}
public class ObserverPatternLambda {
public static void main(String[] args) {
List<Observer> observers = new ArrayList<>();
// Using Streams to register observers
observers.add(message -> System.out.println("Observer 1 received message: " + message));
observers.add(message -> System.out.println("Observer 2 received message: " + message));
// Stream to notify all observers
Stream<String> messageStream = Stream.of("New message arrived!");
messageStream.forEach(message -> observers.forEach(observer -> observer.update(message)));
}
}
ব্যাখ্যা:
- এখানে Stream ব্যবহার করে আমরা সমস্ত অবজার্ভারদের notify করার জন্য ইনলাইন ল্যাম্বডা ব্যবহার করেছি।
forEachমেথড ব্যবহার করে সকল অবজার্ভারদের একযোগে মেসেজ পাঠানো হচ্ছে। এটি Observer Pattern-এর কার্যকারিতা এবং Streams API এর সুবিধা একত্রে প্রদর্শন করে।
3. Command Pattern with Java 8 Lambda
Command Pattern একটি Behavioral Design Pattern যা রিকোয়েস্ট বা অপারেশনকে অবজেক্টে রূপান্তরিত করে এবং প্রয়োজনে সে অপারেশনটি পরে কার্যকরী করা হয়। Java 8 এর Lambda Expressions ব্যবহার করে এটি আরও সহজভাবে বাস্তবায়ন করা যায়।
Traditional Command Pattern Example:
interface Command {
void execute();
}
class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOn();
}
}
class Light {
public void turnOn() {
System.out.println("Light is On");
}
public void turnOff() {
System.out.println("Light is Off");
}
}
class RemoteControl {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
}
}
Lambda-based Command Pattern Example:
import java.util.function.Consumer;
public class CommandPatternLambda {
public static void main(String[] args) {
// Light actions with Lambda
Consumer<String> lightOn = action -> System.out.println("Light is " + action);
// Executing command
lightOn.accept("On");
lightOn.accept("Off");
}
}
ব্যাখ্যা:
- Command Pattern এর ট্র্যাডিশনাল রূপে একটি
execute()মেথড ছিল, যেখানে আলাদা LightOnCommand তৈরি করা হয়েছিল। কিন্তু Lambda ব্যবহার করে আমরা সরাসরিConsumer<String>ব্যবহার করে কোডকে আরও সহজ এবং সংক্ষিপ্ত করেছি। - ল্যাম্বডার মাধ্যমে
lightOn.accept("On")এবংlightOn.accept("Off")কমান্ডগুলি কার্যকর করা হয়েছে।
4. Strategy Pattern with Java 8 Streams
Strategy Pattern হল একটি ডিজাইন প্যাটার্ন যা একটি সমস্যা সমাধানের জন্য একাধিক কৌশল বা স্ট্র্যাটেজি প্রয়োগ করতে সহায়ক। Java 8 Streams API ব্যবহার করে এই প্যাটার্নটি কার্যকরী করা সম্ভব।
Traditional Strategy Pattern Example:
interface SortingStrategy {
void sort(int[] numbers);
}
class BubbleSort implements SortingStrategy {
public void sort(int[] numbers) {
System.out.println("Performing Bubble Sort");
// Sorting logic here
}
}
class QuickSort implements SortingStrategy {
public void sort(int[] numbers) {
System.out.println("Performing Quick Sort");
// Sorting logic here
}
}
class SortContext {
private SortingStrategy strategy;
public SortContext(SortingStrategy strategy) {
this.strategy = strategy;
}
public void executeStrategy(int[] numbers) {
strategy.sort(numbers);
}
}
Lambda and Streams-based Strategy Pattern Example:
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
public class StrategyPatternLambdaStreams {
public static void main(String[] args) {
// Strategy using Lambda
Consumer<List<Integer>> bubbleSort = list -> {
System.out.println("Sorting using Bubble Sort");
list.sort(Integer::compareTo);
};
Consumer<List<Integer>> quickSort = list -> {
System.out.println("Sorting using Quick Sort");
list.sort((a, b) -> b - a);
};
// Creating list of integers
List<Integer> numbers = Arrays.asList(5, 3, 8, 1, 2);
// Sorting using Bubble Sort
bubbleSort.accept(numbers);
System.out.println(numbers);
// Sorting using Quick Sort
quickSort.accept(numbers);
System.out.println(numbers);
}
}
ব্যাখ্যা:
- Lambda Expressions ব্যবহার করে আমরা দুইটি ভিন্ন sorting strategy তৈরি করেছি: একটি Bubble Sort এবং অন্যটি Quick Sort।
- Streams API এর মাধ্যমে সোজা
accept()মেথড ব্যবহার করে সেই স্ট্র্যাটেজি কার্যকর করা হয়েছে।
সারাংশ
Java 8 এর Lambda Expressions এবং Streams API ডিজাইন প্যাটার্নগুলোকে আরও কার্যকর এবং সংক্ষিপ্তভাবে বাস্তবায়ন করার জন্য অত্যন্ত সহায়ক। Strategy, Observer, Command, এবং অন্যান্য ডিজাইন প্যাটার্নগুলি Lambda এবং Streams ব্যবহার করে অনেক সহজে ও দ্রুত কার্যকরী করা যায়। এই প্যাটার্নগুলির মাধ্যমে আপনার কোড হবে আরও পরিষ্কার, স্কেলেবল এবং রক্ষণাবেক্ষণযোগ্য।