شرح Decorator Design Pattern بالتفصيل مع مثال توضيحي ومعرفة العيوب والمميزات
نمط Decorator Design Pattern هو أحد أنماط التصميم السلوكية/الهيكلية (Structural Patterns) في البرمجة الموجهة للكائنات، ويهدف إلى إضافة سلوكيات أو خصائص جديدة للكائنات بشكل ديناميكي دون الحاجة إلى تعديل الكلاس الأصلي أو إنشاء عدد كبير من الوراثات.
يُستخدم هذا النمط عندما نحتاج إلى توسيع وظيفة كائن معين أثناء وقت التشغيل (Runtime)، مع الحفاظ على مبدأ الانفتاح/الإغلاق (Open/Closed Principle). في هذه المقالة سنشرح Decorator Design Pattern بالتفصيل، مع مثال عملي، ثم نوضح كيف تطبّقه Flutter فعليًا من خلال فكرة **Wrap Widget بـ Widget أخرى**.
ما هو Decorator Design Pattern؟
بدلًا من إنشاء كلاس جديد لكل إضافة أو ميزة، يتم استخدام سلسلة من الـ Decorators، حيث يضيف كل Decorator وظيفة محددة فوق الكائن الأصلي.
هذا النمط مناسب جدًا عندما: – تحتاج إلى إضافة خصائص متعددة للكائن. – لا تريد تعديل الكلاس الأصلي. – تريد تجنب التعقيد الناتج عن الوراثة.
سيناريو عملي لتوضيح Decorator Pattern
بدل إنشاء كلاس لكل احتمال، يمكنك استخدام Decorator Pattern لتغليف العنصر الأساسي بعدة Decorators.
مثال بدون استخدام Decorator Pattern
في هذا المثال نقوم بإنشاء كلاس لكل حالة، مما يؤدي إلى تعقيد كبير:
class Button {
void draw() {
print("Drawing button");
}
}
class ColoredButton extends Button {
@override
void draw() {
print("Drawing colored button");
}
}
class BorderedColoredButton extends Button {
@override
void draw() {
print("Drawing colored button with border");
}
}مثال باستخدام Decorator Design Pattern
abstract class WidgetComponent {
void draw();
}
class BasicButton implements WidgetComponent {
@override
void draw() {
print("Drawing basic button");
}
}
abstract class WidgetDecorator implements WidgetComponent {
final WidgetComponent component;
WidgetDecorator(this.component);
}
class ColorDecorator extends WidgetDecorator {
ColorDecorator(super.component);
@override
void draw() {
component.draw();
print("Adding color");
}
}
class BorderDecorator extends WidgetDecorator {
BorderDecorator(super.component);
@override
void draw() {
component.draw();
print("Adding border");
}
}void main() {
WidgetComponent button =
BorderDecorator(ColorDecorator(BasicButton()));
button.draw();
}كيف يطبق Flutter نمط Decorator Design Pattern؟
كل Widget في Flutter يمكن اعتباره Decorator يضيف سلوكًا أو مظهرًا جديدًا فوق Widget أخرى.
مثال Flutter بدون Wrapping
Text(
'Hello Flutter',
)مثال Flutter باستخدام Decorator Pattern (Wrap Widget)
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(8),
boxShadow: [
BoxShadow(
color: Colors.black26,
blurRadius: 4,
)
],
),
child: Center(
child: Text(
'Hello Flutter',
style: TextStyle(color: Colors.white),
),
),
)كل Widget تعمل كـ Decorator فوق الأخرى.
الاختلاف بين النهجين
باستخدام Decorator: – مرونة عالية. – إمكانية دمج أكثر من سلوك. – كود نظيف وقابل للتوسعة.
مميزات وعيوب Decorator Design Pattern
العيوب. – زيادة عدد الكائنات أثناء التشغيل. – قد يصبح تتبع السلوك صعبًا عند كثرة الـ Wrapping. – التعقيد البصري في شجرة الـ Widgets (Widget Tree).
نمط Decorator Design Pattern من أهم الأنماط المستخدمة فعليًا في Flutter، بل يمكن اعتباره أساس بناء الواجهات بالكامل. فكرة Wrap Widget بـ Widget أخرى هي التطبيق العملي المباشر لهذا النمط.
يساعد هذا النمط على كتابة كود مرن، نظيف، وقابل للتوسعة دون المساس بالكود الأصلي.
مثال تشبيهي بسيط: تخيل كوب قهوة أساسي، ثم تضيف له حليب، ثم سكر، ثم كريمة. كل إضافة هي Decorator، والكوب الأساسي لم يتغير.
الخلاصة: يُستخدم Decorator Design Pattern عندما نحتاج إلى إضافة سلوك أو مظهر جديد لكائن موجود بشكل ديناميكي، وهو ما تطبقه Flutter بشكل واضح من خلال Wrapping Widgets داخل Widgets أخرى، مما يجعل الواجهات مرنة وقابلة للتطوير بسهولة.



