Guice-এ Binding একটি গুরুত্বপূর্ণ ধারণা, যা নির্ধারণ করে কিভাবে একটি interface এবং তার সংশ্লিষ্ট concrete class কে একে অপরের সাথে যুক্ত (map) করা হবে। এটি Dependency Injection (DI)-এর মূল অংশ, যেখানে interface-এর ইনস্ট্যান্সের জন্য নির্দিষ্ট একটি implementation সরবরাহ করা হয়।
Guice Binding-এর মাধ্যমে Interface এবং Concrete Class এর মধ্যে Mapping করে এবং তখন সেই Mapping অনুযায়ী নির্ভরশীলতাগুলি (dependencies) ইনজেক্ট করা হয়। Guice দুটি প্রধান পদ্ধতি দিয়ে Binding তৈরি করে:
- Interface to Concrete Class Binding
- Named Binding (যতটা প্রয়োজনীয়)
এখানে আমরা Interface to Concrete Class Binding এর উদাহরণ দেখবো।
Interface থেকে Concrete Class এ Binding - উদাহরণ
ধরা যাক, আমাদের একটি Service ইন্টারফেস এবং তার একটি কনক্রিট (Concrete) ইমপ্লিমেন্টেশন ServiceImpl আছে। Guice ব্যবহার করে আমরা কিভাবে Service ইন্টারফেস এবং ServiceImpl ক্লাসের মধ্যে binding তৈরি করতে পারি, সেটি দেখবো।
Step 1: Define the Interface and Concrete Class
public interface Service {
void serve();
}
public class ServiceImpl implements Service {
@Override
public void serve() {
System.out.println("Service is serving...");
}
}
Step 2: Create a Guice Module to Bind Interface to Concrete Class
Guice-এ, Module হল সেই জায়গা যেখানে আমরা Binding সংজ্ঞায়িত করি। আমাদের ক্ষেত্রে, Service ইন্টারফেসকে ServiceImpl ক্লাসের সাথে bind করতে হবে।
import com.google.inject.AbstractModule;
public class AppModule extends AbstractModule {
@Override
protected void configure() {
bind(Service.class).to(ServiceImpl.class); // Service interface mapped to ServiceImpl class
}
}
এখানে, bind(Service.class).to(ServiceImpl.class) এই লাইনটি Guice-কে বলে যে, যখন Service টাইপের ইনস্ট্যান্স প্রয়োজন হবে, তখন ServiceImpl এর ইনস্ট্যান্স প্রদান করবে।
Step 3: Inject the Dependency in the Client Class
এখন, Client ক্লাসে Service ইন্টারফেস ইনজেক্ট করা হবে।
import com.google.inject.Inject;
public class Client {
private final Service service;
@Inject
public Client(Service service) { // Constructor Injection
this.service = service;
}
public void doSomething() {
service.serve();
}
}
এখানে, @Inject অ্যানোটেশনটি Guice-কে বলে যে এটি Service-এর ইনস্ট্যান্স ইনজেক্ট করবে যখন Client ক্লাস তৈরি হবে।
Step 4: Create the Injector and Run the Application
এখন আমাদের Guice Injector তৈরি করতে হবে এবং Client ক্লাসের ইনস্ট্যান্স গ্রহণ করতে হবে।
import com.google.inject.Guice;
import com.google.inject.Injector;
public class Main {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new AppModule()); // Guice Injector with Module
Client client = injector.getInstance(Client.class); // Dependency Injected
client.doSomething(); // This will call ServiceImpl.serve() method
}
}
কোডের কর্মপ্রবাহ:
- AppModule-এ
bind(Service.class).to(ServiceImpl.class)দ্বারা Service ইন্টারফেসকে ServiceImpl ক্লাসের সাথে যুক্ত করা হয়েছে। - Guice Injector তৈরির মাধ্যমে Client ক্লাসের ইনস্ট্যান্স তৈরি করে এবং ইনজেক্টেড Service কে ServiceImpl ক্লাসের ইনস্ট্যান্স হিসেবে ইনজেক্ট করে।
- Client ক্লাসে
service.serve()কল করার মাধ্যমে ServiceImpl ক্লাসেরserve()মেথড কল হয়।
Binding-এ আরও ফিচার এবং কাস্টমাইজেশন
Guice আরও কিছু Advanced Binding ফিচার প্রদান করে:
Named Bindings:
- যদি একাধিক ইমপ্লিমেন্টেশন থাকে, তবে আপনি নাম (name) দিয়ে নির্দিষ্ট করতে পারেন কোন ইমপ্লিমেন্টেশন ব্যবহার করতে হবে।
bind(Service.class).annotatedWith(Names.named("Service1")).to(ServiceImpl.class);Singleton Scope:
- আপনি
@Singletonঅ্যানোটেশন ব্যবহার করে কোনো ইমপ্লিমেন্টেশনকে সিঙ্গেলটন (singleton) হিসেবে চিহ্নিত করতে পারেন, যাতে তার একটিই ইনস্ট্যান্স তৈরি হয়।
bind(Service.class).to(ServiceImpl.class).in(Singleton.class);- আপনি
Provider Bindings:
- আপনি Guice
Providerব্যবহার করে নির্দিষ্ট সময়ে নির্ভরশীলতাগুলি প্রদান করতে পারেন, যা লেজি লোডিং (lazy loading) সক্ষম করে।
bind(Service.class).toProvider(ServiceProvider.class);- আপনি Guice
Guice-এর Binding ব্যবহার করে সহজে Interface এবং তার Concrete Class এর মধ্যে mapping করা যায়, যা loose coupling, testability, এবং maintainability নিশ্চিত করে। এটি কোডের নির্ভরশীলতাগুলিকে কেন্দ্রীয়ভাবে পরিচালনা করতে সহায়ক, এবং বড় অ্যাপ্লিকেশনগুলির ডিপেনডেন্সি ম্যানেজমেন্ট আরও সহজ করে তোলে।
Read more