মাল্টি-লেভেল ইনহেরিটেন্সের প্রবলেম ও সল্যুশন
সাধারণত যে প্রোগ্রামিং গুলো মাল্টিপল ইনহেরিটেন্স সাপোর্ট করে না, সেই প্রোগ্রামিং ল্যাঙ্গুয়েজ গুলোতে মাল্টিপল ইনহেরিটেন্স এর অনুকরণ করানোর জন্য অনেকেই অনেক সময় মাল্টি লেভেল ইনহেরিটেন্স ব্যবহার করে থাকে। যা একটি সমস্যা সমাধান করলেও নতুন দুইটি সমস্যা তৈরি করে।
সমস্যাগুলো হলঃ
- লজিক্যাল ত্রুটি
- অ্যাপ্লিকেশন বা সফটওয়্যার কে অনেক কমপ্লেক্স করে ফেলে। যার একটি কারণে,[strong] অ্যাপ্লিকেশনে মাঝখানের কোন লেভেলের ইনহেরিটেন্স যদি ভেঙে যায়, তাহলে পুরা অ্যাপ্লিকেশনের ধারা ভেঙে যাবে। [/strong][strong] এপ্লিকেশনে পরিবর্তন আনা খুব কঠিন হয়ে যায় [/strong], যেমন আমরা যদি প্যাডেল এর কোন ভ্যালু চেঞ্জ করতে চাই সেটা করতে আমাদেরকে ক্লাসের ভিতর গিয়ে মডিফাই করতে হবে।
মাল্টি-লেভেল ইনহেরিটেন্সের ধারণাঃ
মাল্টি লেভেল ইনহেরিটেন্সের একটি উদাহরণ ইমেজ দেওয়া হল এছাড়াও ইনহেরিটেন্স সেকশনে এটি নিয়ে বিস্তর আলোচনা করা হয়েছে।
মাল্টি-লেভেল ইনহেরিটেন্সের ক্লাসের উদাহরণ
লিংকঃ http://tpcg.io/_032YJ6
//জাভা (Java) – Multi level inheritance
class Chain {
protected int links;
public Chain(int links) {
this.links = links;
}
protected void showChain() {
System.out.println(“1. Chain – has ” + links + ” links”);
}
}
// A paddle is-a Chain (is-a relation)
class Paddle extends Chain {
private String size;
public Paddle(String size, int links) {
super(links);
this.size = size;
}
protected void showPaddle() {
System.out.println(“2. Paddle – ” + size + ” with ” + getLinks() + ” links”);
}
protected String getSize() {
return size;
}
protected int getLinks() {
return super.links; // super keyword to access the field of the Chain
}
}
// A tire is-a Paddle (is-a relation)
class Tire extends Paddle {
private double diameter;
public Tire(double diameter, String size, int links) {
super(size, links);
this.diameter = diameter;
}
protected void showTire() {
System.out.println(“3. Tire – ” + diameter + ” diameter tire, ” + getSize() + ” paddle with ” + getLinks() + ” links”);
}
}
// A handle is-a Tire (is-a relation)
class Handle extends Tire {
private double length;
private String color;
public Handle(double length, String color) {
super(30, “large”, 100);
this.length = length;
this.color = color;
}
protected void showHandle() {
System.out.println(“4. Handle – ” + length + ” length and ” + color + ” handle”);
}
}
// A seat is-a Handle (is-a relation)
class Seat extends Handle {
private String shape;
public Seat(String shape) {
super(20, “red”);
this.shape = shape;
}
protected void showSeat() {
System.out.println(“5. Seat – ” + shape + ” shape seat”);
}
}
// A body is-a Seat (is-a relation)
class Body extends Seat {
private String material;
public Body(String material) {
super(“round”);
this.material = material;
}
protected void showBody() {
System.out.println(“6. Body – ” + material + ” material body”);
}
}
// A bike is-a Body (is-a relation)
class Bike extends Body {
public Bike(String material) {
super(material);
}
public void showBike() {
System.out.println(“The bike has the following features:”);
showChain();
showPaddle();
showTire();
showHandle();
showSeat();
showBody();
}
}
public class BikeApp {
public static void main(String[] args) {
Bike bike = new Bike(“metal”);
// Displaying the bike details
bike.showBike();
}
}
Output:
//জাভা (Java) – Output The bike has the following features: 1. Chain – has 100 links 2. Paddle – large with 100 links 3. Tire – 30.0 diameter tire, large paddle with 100 links 4. Handle – 20.0 length and red handle 5. Seat – round shape seat 6. Body – metal material body
যদিও code টি কাজ করে এবং এতে কমপ্লেক্সসিটি যোগ হয়েছে, আরেকটি বড় সমস্যা হল লজিক্যাল ত্রুটি, যা বলছে বাইকের হ্যান্ডেল একটি টায়ার যা কখনোই হতে পারে না।
আশা করি সমস্যাগুলো পরিষ্কার যে মাল্টিলেভেল ইনহেরিটেন্স কোডে কমপ্লেক্সিটি, লজিক্যাল ত্রুটি যোগ করে, কোট পরিবর্তন করা হয়ে পড়ে অনেক জটিল।
মাল্টি-লেভেল ইনহেরিটেন্সের সমাধান ইন্টারফেস ব্যবহার করে
লিংকঃ http://tpcg.io/_JI161P
//জাভা (Java) – Multi-level inheritance – Solution with interface
interface Chainable {
public void showChain();
}
interface Paddable {
public void showPaddle();
}
interface Tireable {
public void showTire();
}
interface Handleable {
public void showHandle();
}
interface Seatable {
public void showSeat();
}
interface Bodyable {
public void showBody();
}
class Chain implements Chainable {
public int links;
public Chain(int links) {
this.links = links;
}
@Override
public void showChain() {
System.out.println(“1. Chain – has ” + links + ” links”);
}
}
class Paddle implements Paddable {
private String size;
public Paddle(String size) {
this.size = size;
}
@Override
public void showPaddle() {
System.out.println(“2. Paddle – ” + size);
}
public String getSize() {
return size;
}
}
class Tire implements Tireable {
private double diameter;
public Tire(double diameter) {
this.diameter = diameter;
}
@Override
public void showTire() {
System.out.println(“3. Tire – ” + diameter + ” diameter tire”);
}
}
class Handle implements Handleable {
private double length;
private String color;
public Handle(double length, String color) {
this.length = length;
this.color = color;
}
@Override
public void showHandle() {
System.out.println(“4. Handle – ” + length + ” length and ” + color + ” handle”);
}
}
class Seat implements Seatable {
private String shape;
public Seat(String shape) {
this.shape = shape;
}
@Override
public void showSeat() {
System.out.println(“5. Seat – ” + shape + ” shape seat”);
}
}
class Body implements Bodyable {
private String material;
public Body(String material) {
this.material = material;
}
@Override
public void showBody() {
System.out.println(“6. Body – ” + material + ” material body”);
}
}
class Bike implements Chainable, Paddable, Tireable, Handleable, Seatable, Bodyable {
private Chainable chain; // has-a relation
private Paddable paddle; // has-a relation
private Tireable tire; // has-a relation
private Handleable handle; // has-a relation
private Seatable seat; // has-a relation
private Bodyable body; // has-a relation
// Keeping the constructor for the bike as requested by the user
public Bike(Chainable chain, Paddable paddle, Tireable tire, Handleable handle, Seatable seat, Bodyable body) {
this.chain = chain;
this.paddle = paddle;
this.tire = tire;
this.handle = handle;
this.seat = seat;
this.body = body;
}
public void showBike() {
System.out.println(“The bike has the following features:”);
showChain();
showPaddle();
showTire();
showHandle();
showSeat();
showBody();
}
// Implementing the methods of the interfaces by delegating to the corresponding objects
@Override
public void showChain() {
chain.showChain();
}
@Override
public void showPaddle() {
paddle.showPaddle();
}
@Override
public void showTire() {
tire.showTire();
}
@Override
public void showHandle() {
handle.showHandle();
}
@Override
public void showSeat() {
seat.showSeat();
}
@Override
public void showBody() {
body.showBody();
}
}
public class BikeApp {
public static void main(String[] args) {
Chain chain = new Chain(100);
Paddle paddle = new Paddle(“large”);
Tire tire = new Tire(30);
Handle handle = new Handle(20, “red”);
Seat seat = new Seat(“round”);
Body body = new Body(“metal”);
Bike bike = new Bike(chain, paddle, tire, handle, seat, body);
bike.showBike();
}
}
Output:
//জাভা (Java) – Output The bike has the following features: 1. Chain – has 100 links 2. Paddle – large 3. Tire – 30.0 diameter tire 4. Handle – 20.0 length and red handle 5. Seat – round shape seat 6. Body – metal material body
এই ইন্টারফেসর সমাধানটাতে আমরা খুব সহজেই নতুন আরেকটা কম্পোনেন্ট(Component – Seat, Paddle or different implementation) সংযোজন করতে পারি অথবা যে কোন কম্পনেন্টের ভ্যালু পরিবর্তন করতে পারি। যা করার জন্য আমাদের ক্লাসের (যেমন – Chain, Paddle, Tire ইত্যাদি) কনস্ট্রাক্টর দিয়ে কোন চেঞ্জ করার প্রয়োজন নেই, আমরা এখন Bike ক্লাস তৈরি (Create) যার ফলে এটি একটি খুব ভালো ডিজাইন সাধারণত এভাবেই আমরা ইন্টারফেস ব্যবহার করে এন্টারপ্রাইজ এপ্লিকেশন ডিজাইন করি
এই সমস্যাটিকে আমরা খুব সহজে মাল্টিপেল ইন্টারফেস দিয়ে ইমপ্লিমেন্ট এর মাধ্যমে সমাধান করতে পারি। যার একটি উদাহরণ আমরা ইনহেরিটেন্স এর নতুন মেথড সংযোজন চ্যাপ্টারে আলোচনা করেছি।
অ্যাবস্ট্র্যাক ক্লাস দিয়ে এই সমস্যাটি সমাধান করা যায় না । কারণ হচ্ছে অ্যাবস্ট্রাক্ট ক্লাস তো ক্লাস (যদিও অ্যাবস্ট্রাক্ট), এবং যে প্রোগ্রামিং ল্যাঙ্গুয়েজ (জাভা, সি# ইত্যাদি) মাল্টিপল ইনহেরিটেন্স সাপোর্ট করে না সেই প্রোগ্রামিং ল্যাঙ্গুয়েজে অ্যাবস্ট্রাক্ট ক্লাস ব্যবহার করে এর সমাধান আনা অসম্ভব।