تعارف
۔ اڈاپٹر ڈیزائن پیٹرن ایک مقبول ہے ساختی ڈیزائن پیٹرن سافٹ ویئر انجینئرنگ میں استعمال کیا جاتا ہے۔ یہ گائیڈ دیکھتا ہے کہ ہم Python میں اڈاپٹر ڈیزائن پیٹرن کو کیسے نافذ کر سکتے ہیں۔
ڈیزائن پیٹرن ٹیمپلیٹ کی طرح حل ہیں - سافٹ ویئر کی ترقی میں بار بار آنے والے، عام مسائل کو حل کرنے کی عملی طور پر ترکیبیں۔ اڈاپٹر پیٹرن حقیقی دنیا کے اڈاپٹر کے تصور پر مبنی ہے! مثال کے طور پر، ایک لیپ ٹاپ کے چارجر کے آخر میں 3 پن پلگ ہو سکتا ہے، لیکن وال ساکٹ صرف 2 پن ساکٹ ہو سکتا ہے۔ اس ساکٹ میں 3 پن چارجر لگانے کے لیے، ہمیں ایک اڈاپٹر کی ضرورت ہوگی، جو 3 پن پلگ کو قبول کرے، اور موافقت کرتا ہے میں انٹرفیس 2 پن ساکٹ
ایک 2 پن چارجر اور 3 پن چارجر ہے۔ ایک ہی بنیادی تقریب (ساکٹ سے لیپ ٹاپ تک بجلی چلائیں)، لیکن ہے۔ ایک مختلف شکل، اور کوئی آسانی سے کر سکتا ہے۔ اپنانے دوسرے میں جب بھی آپ کے پاس ایک ہی بنیادی فنکشن کے ساتھ سافٹ ویئر کے اجزاء ہوں لیکن مختلف شکلیں، آپ اڈاپٹر ڈیزائن پیٹرن کو لاگو کرسکتے ہیں۔
اڈاپٹر پیٹرن اس عین اصول کی پیروی کرتا ہے۔ یہ دو غیر مطابقت پذیر انٹرفیس کو ہر ایک جزو کے اندرونی حصوں میں ترمیم کیے بغیر ایک ساتھ کام کرنے کی اجازت دیتا ہے۔ یہ ایک انٹرفیس، دوسرے میں، بیرونی طور پر ڈھال کر حاصل کیا جاتا ہے۔
آئیے اڈاپٹر پیٹرنز کی دنیا میں گہرائی میں جانے سے پہلے کچھ بنیادی اصطلاحات کو دیکھتے ہیں:
- کلائنٹ انٹرفیس: ایک انٹرفیس جو ان افعال کی وضاحت کرتا ہے جو کلائنٹ کو نافذ کرنا چاہئے۔
- کلائنٹ: ایک کلاس جو کلائنٹ انٹرفیس کو نافذ کرتی ہے۔
- ایڈاپٹی/سروس: غیر موازن کلاس جسے کلائنٹ انٹرفیس کے ساتھ تعاون کرنے کی ضرورت ہے۔
- اڈاپٹر: وہ طبقہ جو خدمت اور کلائنٹ کے درمیان تعاون کو ممکن بناتا ہے۔
اڈاپٹر پیٹرنز کی مختلف اقسام
اڈاپٹر ڈیزائن پیٹرن کو دو مختلف طریقوں سے لاگو کیا جا سکتا ہے:
آبجیکٹ اڈاپٹر
اس طریقہ کے ساتھ، اڈاپٹر کلاس کلائنٹ انٹرفیس سے طریقوں کو لاگو کرتی ہے۔ اس طرح، کلائنٹ آبجیکٹ اور اڈاپٹر آبجیکٹ ایک دوسرے کے ساتھ مطابقت رکھتے ہیں۔ سروس آبجیکٹ ایک بناتا ہے۔ has-a
اڈاپٹر آبجیکٹ کے ساتھ تعلق یعنی سروس آبجیکٹ کا تعلق اڈاپٹر آبجیکٹ سے ہے۔
ہم جانتے ہیں کہ سروس کلاس کلائنٹ کے ساتھ مطابقت نہیں رکھتی ہے۔ اڈاپٹر کلاس سروس آبجیکٹ کے ارد گرد لپیٹ کر اس آبجیکٹ کے ساتھ خود کو انسٹینٹیٹ کر دیتی ہے۔ اب، سروس آبجیکٹ تک اڈاپٹر آبجیکٹ کے ذریعے رسائی حاصل کی جا سکتی ہے، جس سے کلائنٹ کو اس کے ساتھ بات چیت کرنے کی اجازت ملتی ہے۔
ہم تمام جدید پروگرامنگ زبانوں میں آبجیکٹ اڈاپٹر کو نافذ کر سکتے ہیں۔
کلاس اڈاپٹر
اس طریقہ کے ساتھ، اڈاپٹر ایک ہے is-a
سروس کلاس کے ساتھ تعلقات. اس منظر نامے میں، اڈاپٹر کلائنٹ کے لیے مطلوبہ طریقوں کو لاگو کرتا ہے، لیکن یہ متعدد اڈاپٹیز سے وراثت میں ملتا ہے، جس سے اسے اپنے غیر مطابقت پذیر افعال کو براہ راست کال کرنے کی صلاحیت ملتی ہے۔ اس تغیر کے ساتھ سب سے بڑی خرابی یہ ہے کہ ہم اسے صرف ان پروگرامنگ زبانوں میں استعمال کر سکتے ہیں جو کلاسز کی متعدد وراثت کو سپورٹ کرتی ہیں۔
ازگر میں اڈاپٹر ڈیزائن پیٹرن کا نفاذ
ذیل کے حصے میں، ہم خاص طور پر استعمال کرتے ہوئے Python میں اڈاپٹر ڈیزائن پیٹرن کو نافذ کریں گے۔ آبجیکٹ اڈاپٹر تغیر. سیکشن کو دو حصوں میں تقسیم کیا گیا ہے۔ سب سے پہلے، ہم وہ ماحول بنائیں گے جہاں اڈاپٹر پیٹرن استعمال کیا جانا چاہیے۔ یہ واضح طور پر دیکھنا ضروری ہے کہ یہ پیٹرن سافٹ ویئر کے کچھ مسائل کو کیسے حل کرسکتا ہے۔ دوسرا حصہ مسئلہ کو حل کرنے کے لیے اڈاپٹر کا استعمال کرے گا۔
کلاسوں کے درمیان عدم مطابقت کا مسئلہ
آئیے مطابقت کے مسئلے کو دیکھتے ہیں جب کلائنٹ اور سروس کلاس مختلف افعال کو نافذ کرتی ہے۔ درج ذیل طریقوں سے کلائنٹ کلاس بنائیں اور اسے فولڈر میں بطور محفوظ کریں۔ 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
کلاس کا کنسٹرکٹر۔ اس اسکرپٹ پر عمل کرنے سے ہمیں درج ذیل آؤٹ پٹ ملتا ہے:
بہترین طرز عمل، صنعت کے لیے منظور شدہ معیارات، اور چیٹ شیٹ کے ساتھ Git سیکھنے کے لیے ہمارے ہینڈ آن، عملی گائیڈ کو دیکھیں۔ گوگلنگ گٹ کمانڈز کو روکیں اور اصل میں سیکھ یہ!
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
ایک اڈاپٹر کا استعمال کرتے ہوئے!
اڈاپٹر ڈیزائن پیٹرن کے فوائد اور نقصانات
اڈاپٹر پیٹرن کے فوائد یہ ہیں:
- ہم اڈاپٹر کلاس اور کلائنٹ کلاس کے درمیان کم جوڑے حاصل کر سکتے ہیں۔
- ہم ایپلی کیشن میں متعدد سروس کلاسز کو شامل کرنے کے لیے اڈاپٹر کلاس کو دوبارہ استعمال کر سکتے ہیں۔
- ہم کلائنٹ کوڈ میں مداخلت کیے بغیر متعدد اڈاپٹر متعارف کروا کر پروگرام کی لچک کو بڑھا سکتے ہیں۔
اڈاپٹر پیٹرن کے نقصانات ہیں:
- اڈاپٹر کلاس اور سروس کلاس کے اضافے کے ساتھ پروگرام کی پیچیدگی بڑھ جاتی ہے۔
- پروگرام میں اوور ہیڈ میں اضافہ ہوتا ہے کیونکہ درخواستیں ایک کلاس سے دوسری کلاس میں بھیجی جاتی ہیں۔
- اڈاپٹر پیٹرن (کلاس اڈاپٹر) ایک سے زیادہ وراثت کا استعمال کرتا ہے، جس کی تمام پروگرامنگ زبانیں حمایت نہیں کرسکتی ہیں۔
نتیجہ
اس مضمون میں، ہم نے اڈاپٹر کے ڈیزائن کے پیٹرن، اس کی اقسام، اور ان کے حل کرنے والے مسائل کے بارے میں سیکھا۔ ہم نے Python میں اڈاپٹر پیٹرن کو نافذ کیا تاکہ ہم a کے ساتھ بات چیت کر سکیں Motorcycle
اعتراض، جیسے a Car
اڈاپٹر کا استعمال کرکے اعتراض کریں تاکہ ہر کلاس کا انٹرفیس تبدیل نہ ہو۔