MapStruct একটি Java-based mapping framework যা compile-time কোড জেনারেট করে, এবং এটি মডেল (DTO) এবং ডোমেইন অবজেক্টগুলির মধ্যে দ্রুত এবং কার্যকরী ম্যাপিং সম্পাদন করতে সহায়তা করে। Inheritance বা উত্তরাধিকার সম্পর্কিত ম্যাপিং হচ্ছে একটি ব্যাপক ফিচার, যেখানে আপনি একটি ক্লাসের বৈশিষ্ট্যগুলি উপরের ক্লাস থেকে উত্তরাধিকার হিসেবে গ্রহণ করেন এবং তারপরে সেগুলিকে ম্যাপ করতে পারেন।
MapStruct এ Inheritance এর মাধ্যমে, আপনি সুপারক্লাস এবং সাবক্লাসের মধ্যে ডেটা ম্যাপিং করতে পারেন, যা কাস্টম ম্যাপিং এবং ডেটা ট্রান্সফার অবজেক্ট (DTO) ব্যবহারকে আরও সহজ এবং কার্যকরী করে তোলে।
১. Inheritance Concept in MapStruct
Inheritance হল একটি অবজেক্ট-ওরিয়েন্টেড প্রোগ্রামিং (OOP) ধারণা, যেখানে একটি ক্লাস তার প্যারেন্ট ক্লাসের বৈশিষ্ট্য এবং আচরণ উত্তরাধিকারীভাবে গ্রহণ করে। MapStruct এ, Inheritance সাপোর্টের মাধ্যমে আপনি প্যারেন্ট ক্লাসের বৈশিষ্ট্যগুলিকে সাবক্লাসে ম্যাপ করতে পারেন।
উদাহরণ: Inheritance Concept
ধরা যাক, আমাদের একটি Person নামক সুপারক্লাস রয়েছে এবং এর একটি সাবক্লাস Employee রয়েছে, যেটি Person ক্লাসের বৈশিষ্ট্যগুলিকে ইনহেরিট করেছে।
// Superclass: Person
public class Person {
private String name;
private int age;
// Getters and Setters
}
// Subclass: Employee
public class Employee extends Person {
private String jobTitle;
// Getters and Setters
}
এখানে, Employee ক্লাসের jobTitle ছাড়াও name এবং age প্যারেন্ট Person ক্লাস থেকে ইনহেরিট করা হয়েছে। এখন আমাদের Person এবং Employee এর মধ্যে ম্যাপিং করতে হবে।
২. MapStruct এ Inheritance ব্যবহার
MapStruct তে Inheritance ব্যবহার করতে হলে, এটি মূলত superclass (প্যারেন্ট ক্লাস) এবং subclass (সাবক্লাস) এর মধ্যে Object Mapping করতে ব্যবহৃত হয়। MapStruct স্বয়ংক্রিয়ভাবে প্যারেন্ট ক্লাসের ফিল্ডগুলো সাবক্লাসে ম্যাপ করতে পারে, তবে সাবক্লাসের জন্য কিছু অতিরিক্ত কাস্টম ম্যাপিং ফাংশন হতে পারে।
উদাহরণ: MapStruct Mapper Interface
ধরা যাক, আমাদের Person এবং Employee এর মধ্যে ম্যাপিং করতে হবে।
PersonMapper.java (MapStruct Interface):
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
@Mapper
public interface PersonMapper {
PersonMapper INSTANCE = Mappers.getMapper(PersonMapper.class);
// Mapping Person to Employee (Inheritance)
@Mapping(source = "name", target = "fullName")
Employee personToEmployee(Person person);
}
এখানে, আমরা Person ক্লাসের name ফিল্ডকে Employee ক্লাসের fullName ফিল্ডে ম্যাপ করেছি। MapStruct প্যারেন্ট ক্লাসের অন্যান্য ফিল্ড (যেমন age) ম্যাপ করবে স্বয়ংক্রিয়ভাবে, এবং কোনো কাস্টম ম্যাপিংয়ের প্রয়োজন না হলে আপনি এটি বাদ দিতে পারেন।
৩. Inheritance with Superclass and Subclass Mapping
ধরা যাক, আপনি যদি Person এবং Employee এর মধ্যে আরো বিস্তারিতভাবে ম্যাপিং করতে চান (যেমন, Employee এর jobTitle এর জন্য কাস্টম ম্যাপিং), তবে আপনি সেই অনুযায়ী কাস্টম ম্যাপিং কোড তৈরি করতে পারেন।
উদাহরণ: Inheritance with Subclass-Specific Mapping
// Superclass: Person
public class Person {
private String name;
private int age;
// Getters and Setters
}
// Subclass: Employee
public class Employee extends Person {
private String jobTitle;
// Getters and Setters
}
// MapStruct Mapper
@Mapper
public interface PersonMapper {
PersonMapper INSTANCE = Mappers.getMapper(PersonMapper.class);
// Mapping Person to Employee (with custom jobTitle mapping)
@Mapping(source = "name", target = "fullName")
@Mapping(source = "jobTitle", target = "position")
Employee personToEmployee(Person person);
}
এখানে, name এবং jobTitle ফিল্ডগুলোকে Employee এর fullName এবং position ফিল্ডে ম্যাপ করা হচ্ছে।
৪. Inheritance with Interface Mapping
MapStruct ইনহেরিটেড ইন্টারফেসও সাপোর্ট করে। আপনি যদি একটি ইন্টারফেসের মাধ্যমে একাধিক ক্লাস ম্যাপ করতে চান, তবে এটি খুবই সহজ।
উদাহরণ: Inheritance with Interface Mapping
// Superclass Interface: Person
public interface Person {
String getName();
int getAge();
}
// Subclass: Employee
public class Employee implements Person {
private String name;
private int age;
private String jobTitle;
// Getters and Setters
}
// Mapper Interface
@Mapper
public interface PersonMapper {
PersonMapper INSTANCE = Mappers.getMapper(PersonMapper.class);
// Mapping Person to Employee
@Mapping(source = "name", target = "fullName")
@Mapping(source = "jobTitle", target = "position")
Employee personToEmployee(Person person);
}
এখানে, Person ইন্টারফেস এবং Employee ক্লাসের মধ্যে MapStruct ম্যাপিং করা হয়েছে, যেখানে PersonMapper মেথডের মাধ্যমে ম্যাপিং করা হচ্ছে।
৫. Inheritance with Multiple Levels
MapStruct একাধিক স্তরের ইনহেরিটেন্স সাপোর্ট করে, অর্থাৎ আপনি যদি একাধিক স্তরের ক্লাস হিরার্কি (যেমন: Grandparent, Parent, Child) ব্যবহার করেন, তবে আপনি এগুলোর মধ্যে ম্যাপিং করতে পারবেন।
উদাহরণ: Multiple Level Inheritance
// Grandparent Class
public class Grandparent {
private String familyName;
// Getters and Setters
}
// Parent Class inheriting Grandparent
public class Parent extends Grandparent {
private String firstName;
// Getters and Setters
}
// Child Class inheriting Parent
public class Child extends Parent {
private String nickname;
// Getters and Setters
}
এখন, MapStruct এর মাধ্যমে এই একাধিক স্তরের ক্লাসগুলোর মধ্যে ডেটা ম্যাপিং করা যেতে পারে।
@Mapper
public interface FamilyMapper {
FamilyMapper INSTANCE = Mappers.getMapper(FamilyMapper.class);
@Mapping(source = "familyName", target = "lastName")
@Mapping(source = "firstName", target = "firstName")
Child parentToChild(Parent parent);
}
এখানে, FamilyMapper মাপারের মাধ্যমে Parent থেকে Child এর মধ্যে ডেটা ম্যাপিং করা হয়েছে।
৬. MapStruct এবং Inheritance এর সুবিধা
- Code Reusability: ইনহেরিটেন্স ব্যবহারের মাধ্যমে আপনি একাধিক ক্লাসের মধ্যে কোড পুনরায় ব্যবহার করতে পারেন।
- Ease of Maintenance: ইনহেরিটেড ক্লাসের মধ্যে মডেল ম্যাপিং সহজে পরিবর্তনযোগ্য হয়, কারণ একবার প্যারেন্ট ক্লাসের ম্যাপিং কনফিগার করলে তা সাবক্লাসে প্রযোজ্য হবে।
- Custom Mapping: সাবক্লাসের জন্য প্রয়োজনীয় কাস্টম ম্যাপিং যুক্ত করা সহজ হয়, যা ডেটা ট্রান্সফার অবজেক্ট (DTO) বা ডোমেইন অবজেক্টের মধ্যে ম্যাপিংকে আরও উন্নত করে।
সারাংশ
Inheritance MapStruct এ একটি শক্তিশালী বৈশিষ্ট্য যা প্যারেন্ট ক্লাস এবং সাবক্লাসের মধ্যে ডেটা ম্যাপিং করতে সহায়তা করে। MapStruct এর মাধ্যমে ইনহেরিটেড ক্লাসগুলির মধ্যে ডেটা ট্রান্সফার অবজেক্ট (DTO) বা ডোমেইন অবজেক্টগুলির মধ্যে দ্রুত এবং কার্যকরী ম্যাপিং করা যায়। এটি কোড পুনরায় ব্যবহার, কাস্টম ম্যাপিং, এবং সহজ রক্ষণাবেক্ষণ নিশ্চিত করে। MapStruct ইনহেরিটেন্সের মাধ্যমে বিভিন্ন স্তরের ক্লাস হিরার্কি, ইন্টারফেস এবং মেথডের মধ্যে সুনির্দিষ্টভাবে ম্যাপিং সম্পাদন করতে সক্ষম।