পাইথনে অ্যাডাপ্টার ডিজাইন প্যাটার্ন

ভূমিকা

সার্জারির অ্যাডাপ্টার ডিজাইন প্যাটার্ন একটি জনপ্রিয় স্ট্রাকচারাল ডিজাইন প্যাটার্ন সফ্টওয়্যার প্রকৌশলে ব্যবহৃত হয়। এই গাইডটি দেখায় কিভাবে আমরা পাইথনে অ্যাডাপ্টার ডিজাইন প্যাটার্ন বাস্তবায়ন করতে পারি।

নকশা নিদর্শন টেমপ্লেট-সদৃশ সমাধান - সফ্টওয়্যার বিকাশে পুনরাবৃত্তিমূলক, সাধারণ সমস্যাগুলি সমাধানের জন্য কার্যত রেসিপি। অ্যাডাপ্টার প্যাটার্ন একটি বাস্তব-বিশ্ব অ্যাডাপ্টারের ধারণার উপর ভিত্তি করে! উদাহরণস্বরূপ, একটি ল্যাপটপের চার্জারের শেষে একটি 3-পিন প্লাগ থাকতে পারে, তবে প্রাচীর সকেটটি শুধুমাত্র 2-পিন সকেট হতে পারে। এই সকেটে একটি 3-পিন চার্জার প্লাগ করার জন্য, আমাদের একটি অ্যাডাপ্টারের প্রয়োজন, যা একটি 3-পিন প্লাগ গ্রহণ করে এবং রূপান্তর মধ্যে ইন্টারফেস 2 পিন সকেট.

একটি 2-পিন চার্জার এবং একটি 3-পিন চার্জার রয়েছে একই মৌলিক ফাংশন (সকেট থেকে ল্যাপটপে বিদ্যুৎ সঞ্চালন), কিন্তু আছে একটি ভিন্ন ফর্ম, এবং কেউ সহজেই করতে পারেন খাপ খাওয়ানো অন্য মধ্যে যখনই আপনার কাছে একই মৌলিক ফাংশন কিন্তু ভিন্ন ফর্ম সহ সফ্টওয়্যার উপাদান থাকে, আপনি অ্যাডাপ্টার ডিজাইন প্যাটার্ন প্রয়োগ করতে পারেন।

অ্যাডাপ্টার প্যাটার্ন এই সঠিক নীতি অনুসরণ করে। এটি প্রতিটি উপাদানের অভ্যন্তরীণ পরিবর্তন না করে দুটি বেমানান ইন্টারফেসকে একসাথে কাজ করার অনুমতি দেয়। এটি বাহ্যিকভাবে, অন্য ইন্টারফেসের সাথে অভিযোজিত করে অর্জন করা হয়।

অ্যাডাপ্টার প্যাটার্নের জগতে আরও গভীরে যাওয়ার আগে আসুন কিছু মৌলিক পরিভাষা দেখি:

  • ক্লায়েন্ট ইন্টারফেস: একটি ইন্টারফেস যে ফাংশন নির্দিষ্ট করে যে ক্লায়েন্ট বাস্তবায়ন করা উচিত.
  • মক্কেল: একটি ক্লাস যা ক্লায়েন্ট ইন্টারফেস প্রয়োগ করে।
  • অভিযোজিত/পরিষেবা: বেমানান ক্লাস যা ক্লায়েন্ট ইন্টারফেসের সাথে সহযোগিতা করতে হবে।
  • এডাপটার: যে শ্রেণী সেবা এবং ক্লায়েন্টের মধ্যে সহযোগিতা সম্ভব করে তোলে।

বিভিন্ন ধরনের অ্যাডাপ্টারের প্যাটার্ন

অ্যাডাপ্টারের নকশা প্যাটার্ন দুটি ভিন্ন উপায়ে প্রয়োগ করা যেতে পারে:

অবজেক্ট অ্যাডাপ্টার

এই পদ্ধতির সাহায্যে, অ্যাডাপ্টার ক্লাস ক্লায়েন্ট ইন্টারফেস থেকে পদ্ধতি প্রয়োগ করে। সুতরাং, ক্লায়েন্ট অবজেক্ট এবং অ্যাডাপ্টার অবজেক্ট একে অপরের সাথে সামঞ্জস্যপূর্ণ। পরিসেবা বস্তুটি একটি গঠন করে has-a অ্যাডাপ্টার অবজেক্টের সাথে সম্পর্ক অর্থাৎ সার্ভিস অবজেক্ট অ্যাডাপ্টার অবজেক্টের অন্তর্গত।

আমরা জানি যে সার্ভিস ক্লাস ক্লায়েন্টের সাথে সামঞ্জস্যপূর্ণ নয়। অ্যাডাপ্টার ক্লাস পরিষেবা বস্তুর চারপাশে মোড়ক করে সেই বস্তুর সাথে নিজেকে ইনস্ট্যান্টিয়েট করে। এখন, সার্ভিস অবজেক্ট অ্যাডাপ্টার অবজেক্টের মাধ্যমে অ্যাক্সেস করা যেতে পারে, ক্লায়েন্টকে এটির সাথে ইন্টারঅ্যাক্ট করতে দেয়।

আমরা সমস্ত আধুনিক প্রোগ্রামিং ভাষায় অবজেক্ট অ্যাডাপ্টার প্রয়োগ করতে পারি।

ক্লাস অ্যাডাপ্টার

এই পদ্ধতির সাথে, অ্যাডাপ্টারের একটি আছে is-a পরিষেবা শ্রেণীর সাথে সম্পর্ক। এই পরিস্থিতিতে, অ্যাডাপ্টারটি ক্লায়েন্টের দ্বারা প্রয়োজনীয় পদ্ধতিগুলি প্রয়োগ করে, তবে এটি একাধিক অ্যাডাপ্টির থেকে উত্তরাধিকারসূত্রে প্রাপ্ত হয়, এটি তাদের বেমানান ফাংশনগুলিকে সরাসরি কল করার ক্ষমতা দেয়। এই বৈচিত্রের সাথে সবচেয়ে বড় অসুবিধা হল যে আমরা এটি শুধুমাত্র প্রোগ্রামিং ভাষায় ব্যবহার করতে পারি যা ক্লাসের একাধিক উত্তরাধিকার সমর্থন করে।

পাইথনে অ্যাডাপ্টার ডিজাইন প্যাটার্ন বাস্তবায়ন

নীচের বিভাগে, আমরা পাইথনে অ্যাডাপ্টার ডিজাইন প্যাটার্ন বাস্তবায়ন করব, বিশেষভাবে ব্যবহার করে অবজেক্ট অ্যাডাপ্টারের বৈচিত্র. বিভাগটি দুটি অংশে বিভক্ত। প্রথমত, আমরা পরিবেশ তৈরি করব যেখানে অ্যাডাপ্টারের প্যাটার্ন ব্যবহার করা উচিত। এই প্যাটার্নটি কীভাবে কিছু সফ্টওয়্যার সমস্যার সমাধান করতে পারে তা স্পষ্টভাবে দেখা গুরুত্বপূর্ণ। দ্বিতীয় বিভাগটি সমস্যা সমাধানের জন্য একটি অ্যাডাপ্টার ব্যবহার করবে।

ক্লাসের মধ্যে অসামঞ্জস্যতা সমস্যা

ক্লায়েন্ট এবং পরিষেবা শ্রেণী যখন বিভিন্ন কার্যকারিতা প্রয়োগ করে তখন সামঞ্জস্যের সমস্যাটি দেখা যাক। নিম্নলিখিত পদ্ধতিগুলির সাথে একটি ক্লায়েন্ট ক্লাস তৈরি করুন এবং এটিকে একটি ফোল্ডারে সংরক্ষণ করুন car.py:

import random

class Car:
    def __init__(self):
        self.generator = random.Random()

    def accelerate(self):
        random_num = self.generator.randint(50, 100)
        speed = random_num
        print(f"The speed of the car is {speed} mph")

    def apply_brakes(self):
        random_num = self.generator.randint(20, 40)
        speed = random_num
        print(f"The speed of the car is {speed} mph after applying the brakes")

    def assign_driver(self, driver_name):
        print(f"{driver_name} is driving the car")

এখানে, আমরা একটি তৈরি করেছি Car তিনটি পদ্ধতি সহ ক্লাস accelerate(), apply_brakes() এবং assign_driver(). আমরা আমদানি করেছি random মডিউল এবং ব্রেকগুলি ত্বরান্বিত এবং প্রয়োগ করার পরে গাড়ির গতি সেট করে এমন নম্বর তৈরি করতে এটি ব্যবহার করে। দ্য assign_driver() পদ্ধতি গাড়ির ড্রাইভারের নাম প্রদর্শন করে।

এর পরে, আমাদের একটি পরিষেবা বা অভিযোজিত শ্রেণী তৈরি করতে হবে যা ক্লায়েন্ট শ্রেণীর সাথে সহযোগিতা করতে চায় Car. এইভাবে একটি মোটরসাইকেল ক্লাস তৈরি করুন এবং এটিকে আপনার ফোল্ডারে সংরক্ষণ করুন motorcycle.py:

import random

class Motorcycle:
    def __init__(self):
        self.generator = random.Random()

    def rev_throttle(self):
        random_num = self.generator.randint(50, 100)
        speed = random_num
        print(f"The speed of the motorcycle is {speed} mph")

    def pull_brake_lever(self):
        random_num = self.generator.randint(20, 40)
        speed = random_num
        print(
            f"The speed of the motorcycle is {speed} mph after applying the brakes")

    def assign_rider(self, rider_name):
        print(f"{rider_name} is riding the motorcycle")  

একটি সার্ভিস ক্লাস, Motorcycle উপরে তিনটি পদ্ধতি দিয়ে তৈরি করা হয়েছে rev_throttle(), pull_brake_lever(), এবং assign_rider(). একই ধরনের কার্যকারিতা থাকা সত্ত্বেও পরিষেবার পদ্ধতি এবং ক্লায়েন্ট শ্রেণীর মধ্যে পার্থক্য লক্ষ্য করুন। দ্য accelerator() পদ্ধতি যখন গাড়ির গতি বাড়ায় rev_throttle() পদ্ধতিটি মোটরসাইকেলের গতি বাড়ায়। একইভাবে, apply_brakes() এবং pull_brake_lever() সংশ্লিষ্ট যানবাহনে ব্রেক প্রয়োগ করে। অবশেষে, দ assign_driver() এবং assign_rider() পদ্ধতি যানবাহন অপারেটর বরাদ্দ.

এর পরে, এই বিভিন্ন পদ্ধতি অ্যাক্সেস করার জন্য একটি ক্লাস তৈরি করা যাক। প্রথমত, একটি যোগ করুন __init.py__ আপনার তৈরি করা একই ফোল্ডারে car.py এবং motorcycle.py:

touch __init__.py

এখন একটি নতুন ফাইলে নিম্নলিখিত কোড যোগ করুন drive.py:

from car import Car
from motorcycle import Motorcycle
import traceback

if __name__ == '__main__':
    car = Car()
    bike = Motorcycle()

    print("The Motorcyclen")
    bike.assign_rider("Subodh")
    bike.rev_throttle()
    bike.pull_brake_lever()
    print("n")

    print("The Carn")
    car.assign_driver("Sushant")
    car.accelerate()
    car.apply_brakes()
    print("n")

    print("Attempting to call client methods with the service objectn")

    try:
        bike.assign_driver("Robert")
        bike.accelerate()
        bike.apply_brakes()
    except AttributeError:
        print("Oops! bike object cannot access car methods")
        traceback.print_exc()

এই স্ক্রিপ্ট যা আমাদের ক্লায়েন্ট এবং পরিষেবা বস্তু তৈরি করে। আমরা প্রথমে আমদানি করি Car এবং Motorcycle ক্লাস করুন এবং তাদের সাথে বস্তু তৈরি করুন। তারপর আমরা থেকে পদ্ধতি আহ্বান bike বস্তু (Motorcycle ক্লাস)। পরে, আমরা পদ্ধতি আহ্বান car বস্তু (Car ক্লাস)। কার্যকর করা হলে, এ পর্যন্ত উল্লিখিত সমস্ত কোড কাজ করবে।

যাইহোক, একটি ব্যতিক্রম উত্থাপিত হয় যখন আমরা পদ্ধতিগুলি আহ্বান করার চেষ্টা করি Car সঙ্গে ক্লাস bike বস্তু যখন আমরা এই স্ক্রিপ্টটি চালাই:

The Motorcycle

Subodh is riding the motorcycle
The speed of the motorcycle is 91 mph
The speed of the motorcycle is 37 mph after applying the brakes


The Car

Sushant is driving the car
The speed of the car is 59 mph
The speed of the car is 33 mph after applying the brakes


Attempting to call client methods with the service object

Oops! bike object cannot access car methods
Traceback (most recent call last):
  File "drive.py", line 24, in 
    bike.assign_driver("Robert")
AttributeError: 'Motorcycle' object has no attribute 'assign_driver'

এই ক্ষেত্রে, আমরা পরিবর্তন করতে পারেন Motorcycle শ্রেণী বা drive.py সঠিক পদ্ধতি ব্যবহার করার জন্য স্ক্রিপ্ট। যাইহোক, অনেক ক্ষেত্রে, আমাদের ক্লায়েন্ট বা পরিষেবা শ্রেণীর সোর্স কোডে অ্যাক্সেস নাও থাকতে পারে। এছাড়াও, এটি একটি সহজ উদাহরণ। বৃহত্তর ক্লায়েন্ট এবং পরিষেবাগুলির সাথে, যদি আমরা অন্য সিস্টেমের সাথে সামঞ্জস্য ভঙ্গ করি তবে তাদের উভয়েরই রিফ্যাক্টর করা সম্ভব হবে না।

পরিবর্তে, আমরা আমাদের ক্লায়েন্ট কোড এবং আমাদের পরিষেবা বস্তুর মধ্যে সামঞ্জস্যপূর্ণ ব্যবধান পূরণ করতে একটি অ্যাডাপ্টার ব্যবহার করতে পারি।

অসঙ্গতি সমস্যা সমাধানের জন্য অ্যাডাপ্টার ব্যবহার করা

একটি নতুন ফাইলে, motorcycle_adapter.py, নিম্নলিখিত ক্লাস যোগ করুন:

class MotorcycleAdapter:

    def __init__(self, motorcycle):
        self.motorcycle = motorcycle

    def accelerate(self):
        self.motorcycle.rev_throttle()

    def apply_brakes(self):
        self.motorcycle.pull_brake_lever()

    def assign_driver(self, name):
        self.motorcycle.assign_rider(name)

আমরা একটি তৈরি MotorcycleAdapter ক্লাস, যা একটি পরিষেবা বস্তুর সাথে নিজেকে তাত্ক্ষণিক করে (motorcycle) অ্যাডাপ্টার ক্লায়েন্ট পদ্ধতি প্রয়োগ করে যা accelerate(), apply_brakes() এবং assign_driver(). শরীরের ভিতরে accelerate() পদ্ধতি, আমরা ব্যবহার করেছি motorcycle কল করার জন্য পরিষেবা বস্তুর উদাহরণ rev_throttle() সেবা পদ্ধতি। একইভাবে, অন্যান্য পদ্ধতিগুলি সংশ্লিষ্ট পদ্ধতিগুলি ব্যবহার করে Motorcycle বর্গ.

এখন, আপডেট করা যাক drive.py তাই আমরা অ্যাডাপ্টারটি ব্যবহার করতে পারি try/except ব্লক:

from car import Car
from motorcycle import Motorcycle
from motorcycle_adapter import MotorcycleAdapter 
import traceback

if __name__ == '__main__':
    car = Car()
    bike = Motorcycle()
    bike_adapter = MotorcycleAdapter(bike) 

    ...

    try:
        print("Attempting to call client methods with the service object using an adaptern")
        bike_adapter.assign_driver("Robert")
        bike_adapter.accelerate()
        bike_adapter.apply_brakes()
    except AttributeError:
        print("Oops! bike object cannot access car methods")
        traceback.print_exc()

এখানে,bike_adapter এর একটি বস্তু MotorcycleAdapter ক্লাস আমরা সরবরাহ করেছি bike আপত্তি MotorcycleAdapter ক্লাসের কনস্ট্রাক্টর। এই স্ক্রিপ্টটি কার্যকর করা আমাদের নিম্নলিখিত আউটপুট দেয়:

সেরা-অভ্যাস, শিল্প-স্বীকৃত মান এবং অন্তর্ভুক্ত চিট শীট সহ গিট শেখার জন্য আমাদের হ্যান্ডস-অন, ব্যবহারিক গাইড দেখুন। গুগলিং গিট কমান্ড এবং আসলে বন্ধ করুন শেখা এটা!

The Motorcycle

Subodh is riding the motorcycle
The speed of the motorcycle is 88 mph
The speed of the motorcycle is 35 mph after applying the brakes


The Car

Sushant is driving the car
The speed of the car is 91 mph
The speed of the car is 24 mph after applying the brakes


Attempting to call client methods with the service object

Attempting to call client methods with the service object using an adapter

Robert is riding the motorcyle
The speed of the motorcycle is 67 mph
The speed of the motorcycle is 25 mph after applying the brakes

অন্তর্নিহিত সমন্বয় না করে Motorcycle ক্লাস, আমরা এটি একটি মত কাজ পেতে পারেন Car একটি অ্যাডাপ্টার ব্যবহার করে!

অ্যাডাপ্টার ডিজাইন প্যাটার্নের সুবিধা এবং অসুবিধা

অ্যাডাপ্টার প্যাটার্নের সুবিধা হল:

  • আমরা অ্যাডাপ্টার ক্লাস এবং ক্লায়েন্ট ক্লাসের মধ্যে কম কাপলিং অর্জন করতে পারি।
  • আমরা অ্যাপ্লিকেশনটিতে অসংখ্য পরিষেবা ক্লাস অন্তর্ভুক্ত করতে অ্যাডাপ্টার ক্লাসটি পুনরায় ব্যবহার করতে পারি।
  • আমরা ক্লায়েন্ট কোডে হস্তক্ষেপ না করে একাধিক অ্যাডাপ্টার প্রবর্তন করে প্রোগ্রামের নমনীয়তা বাড়াতে পারি

অ্যাডাপ্টার প্যাটার্নের অসুবিধাগুলি হল:

  • অ্যাডাপ্টার ক্লাস এবং সার্ভিস ক্লাস যোগ করার সাথে সাথে প্রোগ্রামের জটিলতা বৃদ্ধি পায়।
  • একটি ক্লাস থেকে অন্য ক্লাসে অনুরোধ পাঠানোর কারণে প্রোগ্রামে ওভারহেড বেড়েছে।
  • অ্যাডাপ্টার প্যাটার্ন (ক্লাস অ্যাডাপ্টার) একাধিক উত্তরাধিকার ব্যবহার করে, যা সমস্ত প্রোগ্রামিং ভাষা সমর্থন নাও করতে পারে।

উপসংহার

এই নিবন্ধে, আমরা অ্যাডাপ্টারের ডিজাইন প্যাটার্ন, এর ধরন এবং তারা যে সমস্যাগুলি সমাধান করে সে সম্পর্কে শিখেছি। আমরা পাইথনে অ্যাডাপ্টার প্যাটার্ন প্রয়োগ করেছি যাতে আমরা a এর সাথে যোগাযোগ করতে পারি Motorcycle বস্তু, একটি মত Car একটি অ্যাডাপ্টার ব্যবহার করে বস্তু যাতে প্রতিটি শ্রেণীর ইন্টারফেস পরিবর্তন না হয়।

সময় স্ট্যাম্প:

থেকে আরো Stackabuse