الجزء الثاني: الأنماط البنيوية
3 دقائق قراءة
شرائح الدرس
1 / 13
الغرض: تتعامل هذه الأنماط مع تكوين الكائنات (Object Composition) والعلاقات بين الكيانات المختلفة.
2.1 نمط Adapter
الفكرة الجوهرية: يسمح هذا النمط لواجهات (Interfaces) غير متوافقة بالعمل معًا. تمامًا مثل محوّل الكهرباء (Power Adapter) الذي يتيح لك توصيل جهازك بأنواع مختلفة من المقابس الكهربائية.
classDiagram
class Target {
<<interface>>
+request()
}
class Adapter {
-adaptee: Adaptee
+request()
}
class Adaptee {
+specificRequest()
}
class Client {
+main()
}
Client --> Target
Adapter ..|> Target
Adapter --> Adaptee✅ متى تستخدمه:
- عند دمج مكتبات خارجية (Third-Party Libraries) لها واجهات مختلفة عن واجهتك
- عند دمج كود قديم (Legacy Code) دون الحاجة لتعديله
- لجعل فئات غير متوافقة تعمل معًا
- عندما لا تستطيع تعديل الفئات الموجودة أصلًا
- لإنشاء فئات قابلة لإعادة الاستخدام تعمل مع فئات غير مرتبطة بها
مثال بالكود:
# Old system
class OldPrinter:
def old_print(self, text):
return f"Old printer: {text}"
# New interface expected by client
class ModernPrinter:
def print(self, text):
return f"Modern printer: {text}"
# Adapter to make old printer work with new interface
class PrinterAdapter:
def __init__(self, old_printer):
self.old_printer = old_printer
def print(self, text):
return self.old_printer.old_print(text)
# Client code
def client_code(printer):
return printer.print("Hello World")
# Usage
old_printer = OldPrinter()
adapter = PrinterAdapter(old_printer)
modern_printer = ModernPrinter()
print(client_code(adapter)) # Old printer: Hello World
print(client_code(modern_printer)) # Modern printer: Hello World2.2 نمط Decorator
الفكرة الجوهرية: يضيف هذا النمط وظائف جديدة إلى الكائنات بشكل ديناميكي دون تغيير بنيتها الأساسية. تمامًا مثل إضافة إكسسوارات لغطاء الهاتف.
classDiagram
class Component {
<<interface>>
+operation()
}
class ConcreteComponent {
+operation()
}
class Decorator {
<<abstract>>
-component: Component
+operation()
}
class ConcreteDecoratorA {
+operation()
+addedBehavior()
}
class ConcreteDecoratorB {
+operation()
+addedState
}
Component <|.. ConcreteComponent
Component <|.. Decorator
Decorator <|-- ConcreteDecoratorA
Decorator <|-- ConcreteDecoratorB
Decorator --> Component✅ متى تستخدمه:
- عند إضافة مسؤوليات جديدة للكائنات ديناميكيًا وقت التشغيل
- عندما يؤدي استخدام الوراثة الفرعية (Subclassing) إلى انفجار في عدد الفئات
- لتوسيع الوظائف دون تعديل الكود الموجود
- عندما تحتاج إلى تركيبات مختلفة من السلوكيات
- لإنشاء سلوك قابل للتهيئة (Configurable) للكائنات
مثال بالكود:
from abc import ABC, abstractmethod
class Coffee(ABC):
@abstractmethod
def cost(self):
pass
@abstractmethod
def description(self):
pass
class SimpleCoffee(Coffee):
def cost(self):
return 2.0
def description(self):
return "Simple coffee"
class CoffeeDecorator(Coffee):
def __init__(self, coffee):
self._coffee = coffee
def cost(self):
return self._coffee.cost()
def description(self):
return self._coffee.description()
class Milk(CoffeeDecorator):
def cost(self):
return self._coffee.cost() + 0.5
def description(self):
return self._coffee.description() + ", milk"
class Sugar(CoffeeDecorator):
def cost(self):
return self._coffee.cost() + 0.2
def description(self):
return self._coffee.description() + ", sugar"
# Usage
coffee = SimpleCoffee()
coffee_with_milk = Milk(coffee)
coffee_with_milk_and_sugar = Sugar(coffee_with_milk)
print(f"{coffee_with_milk_and_sugar.description()}: ${coffee_with_milk_and_sugar.cost()}")
# Output: Simple coffee, milk, sugar: $2.72.3 نمط Facade
الفكرة الجوهرية: يوفّر هذا النمط واجهة مبسّطة لنظام فرعي (Subsystem) معقّد. تمامًا مثل ريموت كنترول التلفاز الذي يخفي عنك تعقيد الأنظمة الداخلية للتلفاز.
classDiagram
class Facade {
-subsystem1: SubsystemA
-subsystem2: SubsystemB
-subsystem3: SubsystemC
+operation()
}
class SubsystemA {
+operationA1()
+operationA2()
}
class SubsystemB {
+operationB1()
+operationB2()
}
class SubsystemC {
+operationC1()
+operationC2()
}
class Client {
+main()
}
Client --> Facade
Facade --> SubsystemA
Facade --> SubsystemB
Facade --> SubsystemC✅ متى تستخدمه:
- لتبسيط واجهات برمجة التطبيقات (APIs) أو الأنظمة الفرعية المعقّدة
- لتوفير واجهة موحّدة لمجموعة من الواجهات
- لفصل العملاء (Clients) عن الأنظمة الفرعية المعقّدة
- لإنشاء طبقات من التجريد (Abstraction)
- عندما تريد إخفاء تفاصيل التنفيذ الداخلية
مثال بالكود:
# Complex subsystems
class DVDPlayer:
def on(self):
return "DVD Player is on"
def play(self, movie):
return f"Playing '{movie}'"
def off(self):
return "DVD Player is off"
class SoundSystem:
def on(self):
return "Sound System is on"
def set_volume(self, level):
return f"Volume set to {level}"
def off(self):
return "Sound System is off"
class Projector:
def on(self):
return "Projector is on"
def wide_screen_mode(self):
return "Projector in widescreen mode"
def off(self):
return "Projector is off"
# Facade
class HomeTheaterFacade:
def __init__(self):
self.dvd = DVDPlayer()
self.sound = SoundSystem()
self.projector = Projector()
def watch_movie(self, movie):
actions = [
self.projector.on(),
self.projector.wide_screen_mode(),
self.sound.on(),
self.sound.set_volume(5),
self.dvd.on(),
self.dvd.play(movie)
]
return actions
def end_movie(self):
actions = [
self.dvd.off(),
self.sound.off(),
self.projector.off()
]
return actions
# Usage
theater = HomeTheaterFacade()
print("Starting movie:")
for action in theater.watch_movie("The Matrix"):
print(f" - {action}")