القراء مثلك يساعدون في دعم MUO. عند إجراء عملية شراء باستخدام الروابط الموجودة على موقعنا ، فقد نربح عمولة تابعة. اقرأ أكثر.

أحد أهم المبادئ في تطوير البرمجيات هو مبدأ التصميم المفتوح. يؤكد مبدأ التصميم هذا على أن الفئات يجب أن تكون مفتوحة للتمديد ، لكنها مغلقة للتعديل. يجسد نمط تصميم الديكور مبدأ التصميم المفتوح والمغلق.

باستخدام نمط تصميم الديكور ، يمكنك بسهولة توسيع فئة من خلال إعطائها سلوكًا جديدًا دون تغيير الكود الحالي. يقوم نمط الديكور بهذا بشكل ديناميكي في وقت التشغيل ، باستخدام التكوين. يُعرف نمط التصميم هذا بأنه بديل مرن لاستخدام الوراثة لتوسيع السلوك.

كيف يعمل نمط تصميم الديكور؟

على الرغم من أن نمط الديكور هو بديل ل الميراث الطبقي، فإنه يدمج بعض جوانب الوراثة في تصميمه. يتمثل أحد الجوانب الرئيسية لنمط الديكور في أن جميع فئاته مرتبطة ، إما بشكل مباشر أو غير مباشر.

يحتوي نمط تصميم الديكور النموذجي على الهيكل التالي:

من مخطط الفصل أعلاه ، يمكنك أن ترى أن نمط الديكور يحتوي على أربع فئات رئيسية.

عنصر: هذه فئة مجردة (أو واجهة) ، والتي تعد بمثابة النوع الفائق لنمط الديكور.

مكون الخرسانة: هذه هي الأشياء التي يمكنك تزيينها بسلوكيات مختلفة في وقت التشغيل. يرثون من واجهة المكون ويقومون بتنفيذ وظائفها المجردة.

instagram viewer

مصمم: هذه الفئة مجردة ولها نفس النوع الفائق مثل الكائن الذي ستزينه. في مخطط الفصل ، سترى علاقتين بين فئات المكون وفئة الديكور. العلاقة الأولى هي علاقة الميراث. كل مصمم هو عنصر. العلاقة الثانية هي علاقة تكوين؛ كل مصمم لديه (أو يلتف أ) مكون.

ديكور الخرسانة: هؤلاء هم المصممون الفرديون الذين يمنحون المكون سلوكًا معينًا. يجب أن تلاحظ أن كل مصمم خرساني له متغير حالة يحمل إشارة إلى مكون.

تنفيذ نموذج تصميم الديكور بجافا

يمكن لتطبيق طلب البيتزا النموذجي أن يوضح بشكل كاف كيفية استخدام نمط الديكور لتطوير التطبيقات. يتيح تطبيق البيتزا هذا للعملاء طلب البيتزا مع طبقات متعددة. الطبقة الأولى من نمط الديكور هي واجهة البيتزا:

عامواجهه المستخدمبيتزا{
عامخلاصة خيط وصف();
عامخلاصةمزدوجيكلف();
}

واجهة البيتزا هي فئة المكون. لذلك ، يمكنك إنشاء فئة محددة واحدة أو أكثر منه. تصنع شركة البيتزا نوعين رئيسيين من البيتزا ، بناءً على عجينها. نوع واحد من البيتزا يحتوي على عجينة الخميرة:

عامفصلخميرة البيتزاالأدواتبيتزا{
@تجاوز
عام خيط وصف(){
يعود"عجينة بيتزا مصنوعة من الخميرة";
}

@تجاوز
عاممزدوجيكلف(){
يعود18.00;
}
}

تُعد YeastCrustPizza هي الخرسانة الأولى فئة جافا من واجهة بيتزا. النوع الآخر من البيتزا هو الخبز المسطح:

عامفصلبيتزا فلات بريدجروستالأدواتبيتزا{
@تجاوز
عام خيط وصف(){
يعود"عجينة بيتزا مصنوعة من الخبز المسطح";
}

@تجاوز
عاممزدوجيكلف(){
يعود15.00;
}
}

تعتبر فئة FlatbreadCrustPizza هي المكون الثاني الملموس ، ومثل فئة YeastCrustPizza ، فإنها تنفذ جميع الوظائف المجردة لواجهة البيتزا.

الزخرفة

فئة مصمم الديكور دائمًا ما تكون مجردة ، لذلك لا يمكنك إنشاء مثيل جديد مباشرة منه. لكن من الضروري إقامة علاقة بين مختلف مصممي الديكور والمكونات التي سيقومون بتزيينها.

عامخلاصةفصلتتصدر الديكورالأدواتبيتزا{
عام خيط وصف(){
يعود"تتصدر غير معروف";
}
}

تمثل فئة ToppingDecorator فئة الديكور في هذا التطبيق النموذجي. الآن يمكن لشركة البيتزا إنشاء العديد من الإضافات (أو الزينة) المختلفة ، باستخدام فئة ToppingDecorator. لنفترض أن البيتزا يمكن أن تحتوي على ثلاثة أنواع مختلفة من الإضافات ، وهي الجبن والبيبروني والفطر.

تتصدر الجبن

عامفصلجبنهيمتدتتصدر الديكور{
خاص البيتزا البيتزا؛

عامجبنه(البيتزا البيتزا){
هذا.pizza = بيتزا ؛
}

@تجاوز
عام خيط وصف(){
يعود وصف بيتزا () + "، الجبن تتصدر";
}

@تجاوز
عاممزدوجيكلف(){
يعودبيتزا.يكلف() + 2.50;
}
}

بيبروني تتصدر

عامفصلبيبرونييمتدتتصدر الديكور{
خاص البيتزا البيتزا؛

عامبيبروني(البيتزا البيتزا){
هذا.pizza = بيتزا ؛
}

@تجاوز
عام خيط وصف(){
يعود وصف بيتزا () + "، بيبروني تتصدر";
}

@تجاوز
عاممزدوجيكلف(){
يعودبيتزا.يكلف() + 3.50;
}
}

الفطر يتصدر

عامفصلفطريمتدتتصدر الديكور{
خاص البيتزا البيتزا؛

عامفطر(البيتزا البيتزا){
هذا.pizza = بيتزا ؛
}

@تجاوز
عام خيط وصف(){
يعود وصف بيتزا () + "، الفطر تتصدر";
}

@تجاوز
عاممزدوجيكلف(){
يعودبيتزا.يكلف() + 4.50;
}
}

الآن لديك تطبيق بسيط تم تنفيذه باستخدام نمط تصميم الديكور. إذا طلب العميل بيتزا قشرة الخميرة بالجبن والبيبروني ، فسيظهر رمز الاختبار لهذا السيناريو على النحو التالي:

عامفصلرئيسي{
عامثابتةفارغرئيسي(سلسلة [] args){
بيتزا بيتزا 1 = جديد YeastCrustPizza () ؛
بيتزا 1 = جديد بيبروني (بيتزا 1) ؛
بيتزا 1 = جديد الجبن (بيتزا 1) ؛
System.out.println (pizza1.description () + " $" + pizza1.cost ()) ؛
}
}

سيؤدي تشغيل هذا الرمز إلى إنتاج الإخراج التالي في وحدة التحكم:

كما ترى ، يوضح الإخراج نوع البيتزا إلى جانب تكلفتها الإجمالية. بدأت البيتزا كبيتزا قشرة الخميرة مقابل 18.00 دولارًا ، ولكن مع نمط الديكور ، كان التطبيق قادرًا على إضافة ميزات جديدة وتكلفتها المناسبة للبيتزا. وبالتالي ، إعطاء البيتزا سلوكًا جديدًا دون تغيير الكود الحالي (بيتزا قشرة الخميرة).

باستخدام نمط الديكور ، يمكنك أيضًا تطبيق نفس السلوك على كائن ما عدة مرات كما يحلو لك. إذا طلب أحد العملاء بيتزا بها كل شيء ، وبعض الجبن الإضافي ، فيمكنك تحديث الفصل الرئيسي بالكود التالي ليعكس ذلك:

بيتزا بيتزا 2 = جديد YeastCrustPizza () ؛
بيتزا 2 = جديد بيبروني (بيتزا 2) ؛
بيتزا 2 = جديد الجبن (بيتزا 2) ؛
بيتزا 2 = جديد الجبن (بيتزا 2) ؛
بيتزا 2 = جديد فطر (بيتزا 2) ؛

System.out.println (pizza2.description () + " $" + pizza2.cost ()) ؛

سينتج التطبيق المحدث الإخراج التالي في وحدة التحكم:

مزايا استخدام نمط تصميم الديكور

الميزة الرئيسية لاستخدام نمط تصميم الديكور هي الأمان والمرونة. يسمح لك نمط الزخرفة بتطوير كود أكثر أمانًا من خلال عدم التدخل في الكود الآمن الموجود مسبقًا. بدلا من ذلك يوسع الكود الموجود من خلال التكوين. منع بشكل فعال إدخال الحشرات الجديدة أو الآثار الجانبية غير المقصودة.

نظرًا للتكوين ، يتمتع المطور أيضًا بقدر كبير من المرونة عند استخدام نمط الديكور. يمكنك تنفيذ مصمم ديكور جديد في أي وقت لإضافة سلوك جديد ، دون تغيير الكود الموجود وتعطيل التطبيق.