Functional Programming (FP) হল একটি প্রোগ্রামিং প্যারাডাইম যা ফাংশনগুলোকে প্রথম শ্রেণীর নাগরিক হিসেবে বিবেচনা করে এবং immutable data structures, higher-order functions, pure functions, এবং function composition এর ধারণাগুলি ব্যবহৃত হয়। Java 8 এর পর থেকে Functional Programming আরও জনপ্রিয় হয়ে উঠেছে, কারণ এটি lambda expressions, streams, Optional, এবং functional interfaces এর মতো বৈশিষ্ট্যসমূহ প্রদান করে।
ফাংশনাল প্রোগ্রামিং-এ কিছু প্রাকৃতিক ডিজাইন প্যাটার্ন রয়েছে যা ব্যবহৃত হয়, যার মাধ্যমে কোডের পুনঃব্যবহারযোগ্যতা, নির্ভরযোগ্যতা, এবং মডুলারিটি বৃদ্ধি পায়। এই ডিজাইন প্যাটার্নগুলি Java-তে আরও কার্যকরভাবে প্রয়োগ করা সম্ভব, বিশেষ করে Java 8 এর ফিচারসমূহ ব্যবহারের মাধ্যমে।
এখানে কিছু জনপ্রিয় Functional Programming Design Patterns এবং এগুলির প্রয়োগের উদাহরণ দেওয়া হলো:
Strategy Pattern-এ, একটি এলগরিদমের বিভিন্ন ভ্যারিয়েন্ট তৈরি করা হয় এবং একে অন্যের পরিবর্তে ব্যবহার করা যায়। ফাংশনাল প্রোগ্রামিংয়ে এটি higher-order functions ব্যবহার করে করা হয়। এখানে একটি নির্দিষ্ট কাজের জন্য ভিন্ন ভিন্ন ফাংশন প্রয়োগ করা হয়।
import java.util.function.Function;
public class Main {
public static void main(String[] args) {
// Strategy functions
Function<Integer, Integer> addFive = (x) -> x + 5;
Function<Integer, Integer> multiplyByTwo = (x) -> x * 2;
// Context where strategy is applied
System.out.println("Add five: " + applyStrategy(10, addFive)); // Output: 15
System.out.println("Multiply by two: " + applyStrategy(10, multiplyByTwo)); // Output: 20
}
public static int applyStrategy(int number, Function<Integer, Integer> strategy) {
return strategy.apply(number);
}
}
এখানে applyStrategy()
মেথডের মধ্যে ভিন্ন ভিন্ন functional strategy প্রেরণ করা হচ্ছে, যেমন addFive
এবং multiplyByTwo
। Higher-order function হিসেবে, এখানে ফাংশনগুলোকে প্যারামিটার হিসেবে পাস করা হয়েছে।
Decorator Pattern এমন একটি ডিজাইন প্যাটার্ন, যা একটি অবজেক্টের আচরণ পরিবর্তন করার জন্য ব্যবহার করা হয়। ফাংশনাল প্রোগ্রামিংয়ে এটি function composition এর মাধ্যমে অর্জিত হয়, যেখানে একাধিক ফাংশন একত্রিত করে নতুন ফাংশন তৈরি করা হয়।
import java.util.function.Function;
public class Main {
public static void main(String[] args) {
Function<Integer, Integer> addTen = (x) -> x + 10;
Function<Integer, Integer> multiplyByTwo = (x) -> x * 2;
// Compose functions to decorate the behavior
Function<Integer, Integer> decoratedFunction = addTen.andThen(multiplyByTwo);
System.out.println(decoratedFunction.apply(5)); // Output: 30 (5 + 10 = 15, 15 * 2 = 30)
}
}
এখানে, andThen()
মেথড ব্যবহার করে আমরা addTen এবং multiplyByTwo ফাংশনগুলিকে একত্রিত করেছি (অথবা ডেকোরেট করেছি), এবং ফলস্বরূপ একটি নতুন ফাংশন পেয়েছি যা প্রথমে একটি মানে 10 যোগ করে তারপর 2 দ্বারা গুণ করে।
Observer Pattern হল একটি ডিজাইন প্যাটার্ন যেখানে এক বা একাধিক অবজারভার একটি অবজেক্টের পরিবর্তন সম্পর্কে অবহিত থাকে। ফাংশনাল প্রোগ্রামিংয়ে এটি Event-driven পদ্ধতিতে কাজ করে, যেখানে streams এবং callbacks ব্যবহৃত হয়।
import java.util.*;
import java.util.function.Consumer;
public class Main {
public static void main(String[] args) {
// Observer functions
List<Consumer<String>> observers = new ArrayList<>();
// Add observers (subscribers)
observers.add(msg -> System.out.println("Observer 1: " + msg));
observers.add(msg -> System.out.println("Observer 2: " + msg));
// Notify all observers
notifyObservers(observers, "Event Triggered!");
}
public static void notifyObservers(List<Consumer<String>> observers, String message) {
observers.forEach(observer -> observer.accept(message)); // Each observer receives the message
}
}
এখানে, আমরা Consumer
ফাংশনাল ইন্টারফেস ব্যবহার করে অবজারভার তৈরি করেছি এবং এগুলিকে একটি লিস্টে সংরক্ষণ করেছি। তারপর notifyObservers()
মেথডে আমরা callback এর মাধ্যমে প্রত্যেকটি অবজারভারকে একটি মেসেজ পাঠিয়েছি।
Command Pattern হল এমন একটি ডিজাইন প্যাটার্ন যেখানে কমান্ড (অথবা ফাংশন)গুলিকে আলাদা করে রাখা হয়, এবং পরে তা প্রয়োগ করা হয়। ফাংশনাল প্রোগ্রামিংয়ে, এটি higher-order functions ব্যবহার করে করা যায়, যেখানে কমান্ড হিসেবে ফাংশন পাস করা হয় এবং তা কার্যকর করা হয়।
import java.util.function.Consumer;
public class Main {
public static void main(String[] args) {
// Command: Turn the light on
Consumer<String> turnOnLight = (message) -> System.out.println(message + " Light is ON!");
// Execute the command
executeCommand(turnOnLight, "Action: ");
}
public static void executeCommand(Consumer<String> command, String prefix) {
command.accept(prefix); // Execute the passed command
}
}
এখানে, আমরা Consumer
ফাংশনাল ইন্টারফেস ব্যবহার করে turnOnLight কমান্ড তৈরি করেছি এবং executeCommand()
মেথডে এই কমান্ডটি কার্যকর করেছি।
Factory Pattern একটি ডিজাইন প্যাটার্ন যেখানে অবজেক্ট তৈরির প্রক্রিয়া একটি নির্দিষ্ট ফ্যাক্টরি মেথডের মাধ্যমে নিয়ন্ত্রিত হয়। ফাংশনাল প্রোগ্রামিংয়ে এটি function composition বা function references ব্যবহার করে কার্যকরভাবে অর্জিত হতে পারে।
import java.util.function.Function;
public class Main {
public static void main(String[] args) {
// Factory Function to create a greeting message
Function<String, String> greetingFactory = (name) -> "Hello, " + name + "!";
// Create greeting using factory
System.out.println(greetingFactory.apply("John"));
}
}
এখানে, greetingFactory
ফাংশন একটি factory method হিসেবে কাজ করছে যা নাম পেয়ে একটি greeting message তৈরি করে।
Functional Programming-এর Design Patterns হল ফাংশনাল স্টাইলের ডিজাইন প্যাটার্নগুলো যা ফাংশনাল প্রোগ্রামিংয়ের ধারণাগুলো যেমন higher-order functions, immutable data, এবং function composition ব্যবহার করে কোডকে আরও পরিষ্কার, মডুলার, এবং reusable করে তোলে। Java 8 এবং পরবর্তী সংস্করণে Streams, Lambda Expressions, Functional Interfaces, Optional ইত্যাদি ফিচার ব্যবহারের মাধ্যমে এই প্যাটার্নগুলো কার্যকরভাবে প্রয়োগ করা সম্ভব।
Strategy Pattern একটি Behavioral Design Pattern যা বিভিন্ন এলগরিদম বা আচরণের জন্য একটি ফ্যামিলি প্রদান করে এবং এগুলিকে রানটাইমে ক্লায়েন্ট দ্বারা নির্বাচনযোগ্য করে তোলে। এই প্যাটার্নটি সাধারণত, এলগরিদম বা কার্যপ্রণালীর পরিবর্তনযোগ্যতা বজায় রাখার জন্য ব্যবহৃত হয়।
Functional Programming এর মাধ্যমে, বিশেষ করে Lambda Expressions ব্যবহার করে, আমরা Strategy Pattern-কে আরও সংক্ষিপ্ত এবং পরিষ্কারভাবে ইমপ্লিমেন্ট করতে পারি।
Strategy Pattern এর মূল বিষয় হলো:
এখন, Lambda Expressions ব্যবহার করে আমরা এই প্যাটার্নটিকে আরও compact এবং মডুলারভাবে বাস্তবায়ন করতে পারি। এতে আমরা কৌশল (strategy) হিসাবে ফাংশন বা ল্যাম্বডা ব্যবহার করতে পারব, যা আমাদের কোডকে আরও পরিষ্কার এবং স্বচ্ছ রাখে।
ধরা যাক, আমাদের একটি কৌশল (strategy) সিলেকশন রয়েছে, যেখানে দুটি কৌশল রয়েছে:
আমরা একটি Strategy Interface তৈরি করব, যা একটি সাধারণ মেথড সিগনেচার থাকবে, যেমন execute()
:
@FunctionalInterface
public interface Strategy {
int execute(int a, int b);
}
এখানে, Strategy
ইন্টারফেস একটি Functional Interface যা execute()
মেথডটিকে ডিফাইন করে, যার মাধ্যমে দুটি সংখ্যার উপর কোনো একটি অপারেশন (যেমন, যোগফল বা গুণফল) প্রয়োগ করা হবে।
এবার, আমরা Lambda Expressions ব্যবহার করে কৌশলগুলি সংজ্ঞায়িত করব। এই কৌশলগুলি হবে Strategy
ইন্টারফেসের implementations:
public class StrategyPatternLambdaExample {
public static void main(String[] args) {
// Add strategy using Lambda Expression
Strategy addStrategy = (a, b) -> a + b;
// Multiply strategy using Lambda Expression
Strategy multiplyStrategy = (a, b) -> a * b;
// Context that uses the strategy
System.out.println("Addition: " + executeOperation(5, 3, addStrategy)); // Output: 8
System.out.println("Multiplication: " + executeOperation(5, 3, multiplyStrategy)); // Output: 15
}
// Method to execute operation based on strategy
public static int executeOperation(int a, int b, Strategy strategy) {
return strategy.execute(a, b);
}
}
Strategy
ইন্টারফেস একটি সাধারণ functional interface যা execute()
মেথডটিকে ডিফাইন করে।addStrategy
: এই ল্যাম্বডা এক্সপ্রেশনটি দুইটি সংখ্যার যোগফল বের করার কৌশল।multiplyStrategy
: এই ল্যাম্বডা এক্সপ্রেশনটি দুইটি সংখ্যার গুণফল বের করার কৌশল।executeOperation()
মেথডটি কৌশল নির্বাচন করে এবং তাকে প্রয়োগ করে। এটি Strategy
ইন্টারফেসের একটি ইনস্ট্যান্স নেবে এবং কৌশলটি প্রয়োগ করবে।Addition: 8
Multiplication: 15
Lambda Expressions ব্যবহার করে Strategy Pattern কে Functional Programming স্টাইলে ইমপ্লিমেন্ট করা যায়, যা কোডকে আরও কমপ্যাক্ট, রিডেবল এবং মডুলার করে তোলে। এখানে, Strategy
ইন্টারফেসের মাধ্যমে বিভিন্ন কৌশল এবং তাদের প্রয়োগ করা হয়েছে, যেখানে ল্যাম্বডা এক্সপ্রেশনগুলি কৌশলগুলির আচরণ বাস্তবায়ন করেছে। Lambda এর মাধ্যমে, আপনি সহজে নতুন কৌশল সংজ্ঞায়িত করতে পারেন এবং কোডের নমনীয়তা ও পরিষ্কারতা নিশ্চিত করতে পারেন।
Java Functional Programming-এ Command Pattern এবং Functional Interface দুটি শক্তিশালী ধারণা, যা কোডকে আরও নমনীয়, পরিষ্কার এবং মডুলার করতে সহায়তা করে। Command Pattern একটি Behavioral Design Pattern যা একটি অপারেশনকে একটি অবজেক্টে পরিণত করে, যাতে তা পুনরায় কার্যকর করা যায় এবং অন্য ক্লাসের মধ্যে পাস করা যায়। এই প্যাটার্নটি ফাংশনাল প্রোগ্রামিংয়ের সাথে একত্রিত হলে, কোডের কার্যকারিতা আরও শক্তিশালী ও কমপ্যাক্ট হয়ে ওঠে।
Command Pattern মূলত একটি request বা action কে একটি command object-এ encapsulate করে, যাতে সেই কমান্ডটি প্রয়োগ করা যায় এবং প্রয়োজনে সহজে পরিচালনা বা undo করা যায়। এটি ব্যবহার করা হয় যখন আপনি চান যে, client এবং receiver এর মধ্যে শক্তিশালী decoupling হোক।
Command Pattern-এর মূল কম্পোনেন্ট:
Functional Interface হল একটি ইন্টারফেস যা শুধুমাত্র একটি abstract method ধারণ করে। এটি lambda expressions এবং method references ব্যবহার করতে সক্ষম, যা Command Pattern-এর কার্যকারিতা আরও সংক্ষিপ্ত এবং পরিষ্কার করে তোলে।
Java-তে Functional Interface ব্যবহার করে Command Pattern বাস্তবায়ন করার উদাহরণ দেওয়া হবে।
এখানে, আমরা Command Pattern ব্যবহার করে একটি functional interface (যেমন Command
interface) তৈরি করব এবং তার মধ্যে lambda expressions ব্যবহার করব।
প্রথমে, Command Interface তৈরি করি, যা execute মেথড ডিফাইন করবে:
@FunctionalInterface
public interface Command {
void execute();
}
এটি একটি Functional Interface, কারণ এতে শুধুমাত্র একটি abstract method (এখানে execute()
) রয়েছে। এটি ফাংশনাল প্রোগ্রামিংয়ের lambda expression বা method references দ্বারা প্রয়োগ করা যাবে।
এখন, আমরা কিছু কনক্রিট কমান্ড ক্লাস তৈরি করব যেগুলি Command ইন্টারফেস ইমপ্লিমেন্ট করবে এবং বিশেষ ধরনের actions (যেমন প্রিন্টিং, অ্যাডিশন) সম্পাদন করবে।
public class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOn();
}
}
public class LightOffCommand implements Command {
private Light light;
public LightOffCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOff();
}
}
এখানে, LightOnCommand এবং LightOffCommand দুটি Command ইন্টারফেস ইমপ্লিমেন্ট করেছে, যা যথাক্রমে লাইট অন এবং অফ করার জন্য বাস্তবায়িত হয়েছে।
এখন, আমরা Receiver ক্লাসটি তৈরি করি, যা আসলে কার্যক্রম বাস্তবায়ন করবে:
public class Light {
public void turnOn() {
System.out.println("The light is ON");
}
public void turnOff() {
System.out.println("The light is OFF");
}
}
এখানে, Light ক্লাস একটি রিসিভার হিসেবে কাজ করছে যা আসলে turnOn এবং turnOff অপারেশনগুলি বাস্তবায়ন করবে।
এখন, আমরা Invoker ক্লাস তৈরি করব, যা কমান্ডটি চালু করবে:
public class RemoteControl {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
}
}
এখানে, RemoteControl ক্লাসটি Command ইন্টারফেসের ইনস্ট্যান্স গ্রহণ করে এবং তারপরে pressButton()
মেথডের মাধ্যমে execute() মেথডটি কল করবে।
এখন, আমরা এই সব ক্লাসকে একত্রে ব্যবহার করে একটি উদাহরণ তৈরি করি:
public class CommandPatternExample {
public static void main(String[] args) {
Light light = new Light();
// Creating concrete command objects
Command lightOn = new LightOnCommand(light);
Command lightOff = new LightOffCommand(light);
// Creating invoker object
RemoteControl remote = new RemoteControl();
// Turning the light on
remote.setCommand(lightOn);
remote.pressButton(); // Output: The light is ON
// Turning the light off
remote.setCommand(lightOff);
remote.pressButton(); // Output: The light is OFF
}
}
এখানে, RemoteControl ক্লাসটি Command অবজেক্টের মাধ্যমে কাজ করছে, যা বাস্তবিকভাবে Light রিসিভারের কার্যকলাপ চালাচ্ছে।
Functional Interface ব্যবহার করার সুবিধা হল, আপনি lambda expressions এর মাধ্যমে কমান্ডগুলি আরো সংক্ষিপ্তভাবে এবং কার্যকরভাবে লেখতে পারবেন। নিচে দেখানো হল কিভাবে আমরা lambda expressions ব্যবহার করতে পারি:
public class CommandPatternWithLambda {
public static void main(String[] args) {
// Creating the light object
Light light = new Light();
// Using lambda expressions for commands
Command lightOn = () -> light.turnOn();
Command lightOff = () -> light.turnOff();
// Creating invoker object
RemoteControl remote = new RemoteControl();
// Turning the light on using lambda expression
remote.setCommand(lightOn);
remote.pressButton(); // Output: The light is ON
// Turning the light off using lambda expression
remote.setCommand(lightOff);
remote.pressButton(); // Output: The light is OFF
}
}
এখানে, lightOn
এবং lightOff
কমান্ডগুলি lambda expressions দিয়ে সংজ্ঞায়িত করা হয়েছে। এটি কোডকে আরও সংক্ষিপ্ত এবং পাঠযোগ্য করে তুলেছে।
Command Pattern এবং Functional Interface ব্যবহার করার কিছু গুরুত্বপূর্ণ সুবিধা হল:
Command Pattern এবং Functional Interface Java-তে functional programming কৌশল ব্যবহার করতে অত্যন্ত কার্যকরী। এটি কোডকে বেশি modular, extensible, এবং decoupled করে তোলে। Java 8 এবং পরবর্তী সংস্করণে lambda expressions এবং method references ব্যবহার করে এই প্যাটার্নটি আরও সোজা এবং কার্যকরী হয়ে ওঠে। Command Pattern আপনার কোডের কার্যকরীতা এবং রক্ষণাবেক্ষণযোগ্যতা বৃদ্ধি করতে সহায়তা করে, বিশেষ করে যখন আপনি বিভিন্ন অ্যাকশন বা অপারেশনকে পুনরায় ব্যবহারযোগ্য অবজেক্টে পরিণত করতে চান।
Factory Pattern একটি ডিজাইন প্যাটার্ন যা object creation এর প্রক্রিয়াকে কনট্রোল করে এবং ক্লাসের উদাহরণ তৈরি করতে একটি একক পদ্ধতি প্রদান করে। সাধারণত, Factory Pattern ইম্প্লিমেন্টেশন সাধারণভাবে একটি মেথড ব্যবহার করে যা অবজেক্ট তৈরি করে এবং ফিরিয়ে দেয়।
এটি সাধারণত object creation logic থেকে ক্লাসের ব্যবহারকারীকে আলাদা করার জন্য ব্যবহৃত হয়। Functional Programming এ, আমরা ফ্যাক্টরি প্যাটার্নকে Function বা Supplier ইন্টারফেস ব্যবহার করে কার্যকরভাবে বাস্তবায়িত করতে পারি।
ফ্যাক্টরি প্যাটার্ন সাধারণত একটি ক্লাসের ইন্সট্যান্স তৈরি করার জন্য ব্যবহৃত হয়। Functional Programming এর মাধ্যমে, আপনি Factory Function তৈরি করতে পারেন যা একটি Function বা Supplier ব্যবহার করে একটি নতুন অবজেক্ট তৈরি করবে এবং ফিরিয়ে দেবে।
Java 8 থেকে Functional Interfaces এবং Lambda Expressions ব্যবহৃত হওয়া শুরু করেছে। এগুলি আমাদের ক্লাস বা অবজেক্ট তৈরি করতে ফাংশনাল পদ্ধতিতে ফ্যাক্টরি প্যাটার্ন বাস্তবায়িত করতে সাহায্য করে।
এখানে আমরা একটি Product ইন্টারফেস তৈরি করবো এবং একটি ফ্যাক্টরি ফাংশন ব্যবহার করে এই অবজেক্ট তৈরি করবো।
Product
ইন্টারফেস তৈরি করাপ্রথমে, একটি সাধারণ Product
ইন্টারফেস তৈরি করি যা কিছু প্রোপার্টি রাখবে।
public interface Product {
void display();
}
Product
এর দুটি বাস্তবায়ন তৈরি করাএখন, আমরা দুটি কনক্রিট ক্লাস তৈরি করবো যা Product
ইন্টারফেসটি ইমপ্লিমেন্ট করবে।
public class ConcreteProductA implements Product {
@Override
public void display() {
System.out.println("Product A");
}
}
public class ConcreteProductB implements Product {
@Override
public void display() {
System.out.println("Product B");
}
}
এখন, আমরা Functional Interface ব্যবহার করে Factory Pattern এর কার্যকরী ফাংশন তৈরি করবো। এখানে Function<T, R> বা Supplier ব্যবহার করে একটি Factory Function তৈরি করা যাবে।
import java.util.function.Supplier;
public class FunctionalFactory {
// Factory method using Supplier
public static Supplier<Product> getProduct(String type) {
if ("A".equalsIgnoreCase(type)) {
return ConcreteProductA::new;
} else if ("B".equalsIgnoreCase(type)) {
return ConcreteProductB::new;
}
throw new IllegalArgumentException("Unknown product type");
}
public static void main(String[] args) {
// Using the factory function to create Product A
Product productA = getProduct("A").get();
productA.display(); // Output: Product A
// Using the factory function to create Product B
Product productB = getProduct("B").get();
productB.display(); // Output: Product B
}
}
এখানে:
ConcreteProductA::new
এবং ConcreteProductB::new
ব্যবহার করে যথাক্রমে Product A এবং Product B তৈরি করছি।get()
মেথড ব্যবহার করে প্রোডাক্টের ইন্সট্যান্স তৈরি করা হচ্ছে এবং তার পর display()
মেথডটি কল করা হচ্ছে।এটি Functional Programming ধারণা ব্যবহার করে Factory Pattern এর একটি কার্যকরী বাস্তবায়ন। এখানে, কোডটি declarative এবং immutable এবং lambda expression এবং Supplier ব্যবহৃত হয়েছে। এর ফলে কোড আরও পরিষ্কার এবং পুনঃব্যবহারযোগ্য হয়েছে।
Template Method Pattern একটি Behavioral Design Pattern যা একটি অ্যালগরিদমের মৌলিক কাঠামো নির্ধারণ করে এবং কিছু স্টেপের জন্য সাবক্লাসে কাস্টম লজিক (যথা: hook methods) বাস্তবায়ন করতে দেয়। এটি সাধারনত abstract class বা interface এর মাধ্যমে ডিজাইন করা হয় যেখানে মূল অ্যালগরিদমের স্টেপগুলির ভিত্তি নির্ধারিত থাকে, এবং সাবক্লাসে কাস্টম লজিক প্রয়োগ করা হয়।
ফাংশনাল প্রোগ্রামিং প্যারাডাইমে Template Method Pattern এর বাস্তবায়ন কিছুটা ভিন্ন হয়। এখানে Lambda Expressions এবং Higher-order functions ব্যবহার করে আপনি Template Method Pattern বাস্তবায়ন করতে পারেন, যা কোডের নমনীয়তা এবং পুনঃব্যবহারযোগ্যতা বৃদ্ধি করে।
এখানে Template Method Pattern এর functional approach ব্যবহার করে উদাহরণ দেখানো হলো।
প্রথাগতভাবে, Template Method Pattern একটি abstract class ব্যবহার করে বাস্তবায়িত হয়, যেখানে আপনি মূল অ্যালগরিদমের কাঠামো নির্ধারণ করেন এবং কিছু স্টেপ সাবক্লাসে কাস্টমাইজ করতে দেন।
abstract class Game {
// Template method
public void play() {
initializeGame();
startPlay();
endPlay();
}
// Abstract methods to be implemented by subclasses
abstract void initializeGame();
abstract void startPlay();
abstract void endPlay();
}
class Football extends Game {
@Override
void initializeGame() {
System.out.println("Football game initialized.");
}
@Override
void startPlay() {
System.out.println("Football game started.");
}
@Override
void endPlay() {
System.out.println("Football game ended.");
}
}
class Basketball extends Game {
@Override
void initializeGame() {
System.out.println("Basketball game initialized.");
}
@Override
void startPlay() {
System.out.println("Basketball game started.");
}
@Override
void endPlay() {
System.out.println("Basketball game ended.");
}
}
public class TemplateMethodPatternExample {
public static void main(String[] args) {
Game football = new Football();
football.play();
System.out.println("\n");
Game basketball = new Basketball();
basketball.play();
}
}
Explanation:
Java 8 এবং তার পরবর্তী সংস্করণে Functional Programming ধারণা অন্তর্ভুক্ত হওয়ায়, আপনি Template Method Pattern ফাংশনাল স্টাইলেও প্রয়োগ করতে পারেন। এর জন্য higher-order functions, lambda expressions, এবং functional interfaces ব্যবহার করা হয়।
import java.util.function.Consumer;
public class FunctionalTemplateMethodPattern {
// Template method using lambda expressions and higher-order functions
public static void playGame(Consumer<Void> initialize, Consumer<Void> start, Consumer<Void> end) {
initialize.accept(null);
start.accept(null);
end.accept(null);
}
public static void main(String[] args) {
// For Football Game
Consumer<Void> footballInitialize = v -> System.out.println("Football game initialized.");
Consumer<Void> footballStart = v -> System.out.println("Football game started.");
Consumer<Void> footballEnd = v -> System.out.println("Football game ended.");
playGame(footballInitialize, footballStart, footballEnd);
System.out.println("\n");
// For Basketball Game
Consumer<Void> basketballInitialize = v -> System.out.println("Basketball game initialized.");
Consumer<Void> basketballStart = v -> System.out.println("Basketball game started.");
Consumer<Void> basketballEnd = v -> System.out.println("Basketball game ended.");
playGame(basketballInitialize, basketballStart, basketballEnd);
}
}
Explanation:
playGame
মেথডটি একটি template method যা তিনটি স্টেপ গ্রহণ করে: initialize
, start
, এবং end
। এই তিনটি স্টেপ একটি Consumer<Void>
ফাংশনাল ইন্টারফেস হিসেবে পাস করা হয়েছে, যা lambda expressions ব্যবহার করে কাস্টম লজিক কার্যকরী করছে।
Java তে Template Method Pattern এর functional programming পদ্ধতিতে বাস্তবায়ন করা অনেক বেশি নমনীয় এবং পরিষ্কার হয়। Higher-order functions এবং lambda expressions ব্যবহার করে আমরা এই প্যাটার্নের বিভিন্ন স্টেপ কাস্টমাইজ করতে পারি, যা কোডের পুনঃব্যবহারযোগ্যতা এবং মেইনটেনেবিলিটি বাড়ায়। এই পদ্ধতি আপনাকে object-oriented design এর পাশাপাশি functional programming এর সুবিধা দেয়, যা কোডের কার্যকারিতা এবং পরিষ্কারতা উন্নত করে।
Read more