الواجهة (Facade).
الواجهة (Facade) هي نمط تصميم هيكلي يوفر واجهة مبسطة لمكتبة أو إطار عمل أو أي مجموعة معقدة أخرى من الفئات.
##Intent
الواجهة (Facade) هي نمط تصميم هيكلي يوفر واجهة مبسطة لمكتبة أو إطار عمل أو أي مجموعة معقدة أخرى من الفئات.

##Problem
تخيل أنك بحاجة إلى جعل الكود الخاص بك يعمل مع مجموعة واسعة من الكائنات التي تنتمي إلى مكتبة أو إطار عمل متطور. في العادة، ستحتاج إلى تهيئة جميع تلك الكائنات، وتتبع التبعيات، وتنفيذ الأساليب بالترتيب الصحيح، وما إلى ذلك.
نتيجةً لذلك، سيصبح منطق الأعمال في فئاتك مقترنًا بشكل وثيق بتفاصيل تنفيذ فئات الطرف الثالث، مما يجعل فهمه وصيانته أمرًا صعبًا.
##Solution
الواجهة هي فئة توفر واجهة بسيطة لنظام فرعي معقد يحتوي على الكثير من الأجزاء المتحركة. قد توفر الواجهة وظائف محدودة مقارنةً بالتعامل مع النظام الفرعي مباشرة. غير أنها تتضمن فقط تلك الميزات التي يهتم بها العملاء فعلاً.
يُعدّ استخدام الواجهة مفيدًا عندما تحتاج إلى دمج تطبيقك مع مكتبة متطورة تحتوي على عشرات الميزات، لكنك تحتاج فقط إلى جزء صغير من وظائفها.
على سبيل المثال، قد يستخدم تطبيق يرفع مقاطع فيديو قصيرة ومضحكة عن القطط إلى منصات التواصل الاجتماعي مكتبة تحويل فيديو احترافية. غير أن كل ما يحتاجه هو فئة تحتوي على الأسلوب الواحد encode(filename, format). بعد إنشاء هذه الفئة وربطها بمكتبة تحويل الفيديو، ستحصل على أولى واجهاتك.
##Structure
-
توفر الواجهة (Facade) وصولاً ملائمًا إلى جزء معين من وظائف النظام الفرعي. تعرف أين توجّه طلب العميل وكيف تُشغّل جميع الأجزاء المتحركة.
-
يمكن إنشاء فئة واجهة إضافية (Additional Facade) لتجنب تلويث واجهة واحدة بميزات غير ذات صلة قد تجعلها بنية معقدة أخرى. يمكن استخدام الواجهات الإضافية من قِبَل كل من العملاء والواجهات الأخرى.
-
يتكوّن النظام الفرعي المعقد (Complex Subsystem) من عشرات الكائنات المتنوعة. لجعلها جميعها تُنجز شيئًا مفيدًا، يجب التعمق في تفاصيل تنفيذ النظام الفرعي، مثل تهيئة الكائنات بالترتيب الصحيح وتزويدها بالبيانات بالصيغة المناسبة.
لا تعلم فئات النظام الفرعي بوجود الواجهة. تعمل داخل النظام وتتعامل مع بعضها مباشرة.
-
يستخدم العميل (Client) الواجهة بدلاً من استدعاء كائنات النظام الفرعي مباشرة.
##Pseudocode
في هذا المثال، يبسّط نمط الواجهة (Facade) التفاعل مع إطار عمل تحويل الفيديو المعقد.

مثال على عزل تبعيات متعددة داخل فئة واجهة واحدة.
بدلاً من جعل الكود الخاص بك يعمل مع عشرات فئات إطار العمل مباشرة، تقوم بإنشاء فئة واجهة تُغلّف تلك الوظائف وتُخفيها عن بقية الكود. تساعد هذه البنية أيضًا على تقليل الجهد المبذول عند الترقية إلى إصدارات مستقبلية من إطار العمل أو استبداله بآخر. الشيء الوحيد الذي ستحتاج إلى تغييره في تطبيقك هو تنفيذ أساليب الواجهة.
// هذه بعض فئات إطار عمل تحويل الفيديو المعقد التابع لطرف ثالث.
// لا نتحكم في هذا الكود، وبالتالي لا يمكننا تبسيطه.
class VideoFile
// ...
class OggCompressionCodec
// ...
class MPEG4CompressionCodec
// ...
class CodecFactory
// ...
class BitrateReader
// ...
class AudioMixer
// ...
// ننشئ فئة واجهة لإخفاء تعقيد إطار العمل
// خلف واجهة بسيطة. وهو مقايضة بين الوظائف والبساطة.
class VideoConverter is
method convert(filename, format):File is
file = new VideoFile(filename)
sourceCodec = (new CodecFactory).extract(file)
if (format == "mp4")
destinationCodec = new MPEG4CompressionCodec()
else
destinationCodec = new OggCompressionCodec()
buffer = BitrateReader.read(filename, sourceCodec)
result = BitrateReader.convert(buffer, destinationCodec)
result = (new AudioMixer()).fix(result)
return new File(result)
// فئات التطبيق لا تعتمد على الكثير من الفئات
// التي يوفرها إطار العمل المعقد. كذلك، إذا قررت
// التبديل إلى إطار عمل آخر، فأنت بحاجة فقط إلى إعادة كتابة فئة الواجهة.
class Application is
method main() is
convertor = new VideoConverter()
mp4 = convertor.convert("funny-cats-video.ogg", "mp4")
mp4.save()
##Applicability
استخدم نمط الواجهة (Facade) عندما تحتاج إلى واجهة محدودة لكنها مباشرة مع نظام فرعي معقد.
في الغالب، تزداد الأنظمة الفرعية تعقيدًا مع مرور الوقت. حتى تطبيق أنماط التصميم يؤدي عادةً إلى إنشاء المزيد من الفئات. قد يصبح النظام الفرعي أكثر مرونة وأسهل إعادة استخدامًا في سياقات مختلفة، لكن كمية الإعدادات والكود النمطي (boilerplate) التي يطلبها من العميل تتزايد باستمرار. تحاول الواجهة إصلاح هذه المشكلة بتوفير اختصار للميزات الأكثر استخدامًا في النظام الفرعي والتي تناسب معظم متطلبات العملاء.
استخدم الواجهة عندما تريد تنظيم نظام فرعي في طبقات.
أنشئ واجهات لتحديد نقاط الدخول إلى كل مستوى من مستويات النظام الفرعي. يمكنك تقليل الاقتران بين أنظمة فرعية متعددة عن طريق إلزامها بالتواصل فقط عبر الواجهات.
على سبيل المثال، لنعد إلى إطار عمل تحويل الفيديو الخاص بنا. يمكن تقسيمه إلى طبقتين: واحدة تتعلق بالفيديو وأخرى بالصوت. يمكنك لكل طبقة إنشاء واجهة، ثم جعل فئات كل طبقة تتواصل مع بعضها عبر تلك الواجهات. يشبه هذا النهج إلى حد كبير نمط الوسيط (Mediator).
##How to Implement
-
تحقق مما إذا كان بالإمكان توفير واجهة أبسط مما يوفره النظام الفرعي الحالي بالفعل. أنت على الطريق الصحيح إذا كانت هذه الواجهة تجعل كود العميل مستقلاً عن كثير من فئات النظام الفرعي.
-
أعلن عن هذه الواجهة ونفّذها في فئة واجهة جديدة. يجب أن تعيد الواجهة توجيه الاستدعاءات من كود العميل إلى الكائنات المناسبة في النظام الفرعي. ينبغي أن تكون الواجهة مسؤولة عن تهيئة النظام الفرعي وإدارة دورة حياته اللاحقة ما لم يكن كود العميل يتولى ذلك مسبقًا.
-
للاستفادة الكاملة من النمط، اجعل جميع كود العميل يتواصل مع النظام الفرعي فقط عبر الواجهة. الآن أصبح كود العميل محميًا من أي تغييرات في كود النظام الفرعي. على سبيل المثال، عند ترقية النظام الفرعي إلى إصدار جديد، ستحتاج فقط إلى تعديل الكود في الواجهة.
-
إذا أصبحت الواجهة كبيرة جدًا، فكّر في استخراج جزء من سلوكها إلى فئة واجهة جديدة ومحسّنة.
##Pros & Cons
- يمكنك عزل الكود الخاص بك عن تعقيدات النظام الفرعي.
- يمكن أن تصبح الواجهة كائن إله (god object) مقترنًا بجميع فئات التطبيق.
##Relations with Other Patterns
-
الواجهة (Facade) تُعرّف واجهة جديدة للكائنات الموجودة، في حين يحاول المهايئ (Adapter) جعل الواجهة الحالية قابلة للاستخدام. عادةً ما يلف المهايئ كائنًا واحدًا فقط، بينما تعمل الواجهة مع نظام فرعي كامل من الكائنات.
-
يمكن أن يكون المصنع المجرد (Abstract Factory) بديلاً لـ الواجهة (Facade) عندما تريد فقط إخفاء طريقة إنشاء كائنات النظام الفرعي من كود العميل.
-
يُوضح الكائن الخفيف (Flyweight) كيفية إنشاء كميات كبيرة من الكائنات الصغيرة، بينما تُوضح الواجهة (Facade) كيفية إنشاء كائن واحد يمثل نظامًا فرعيًا بأكمله.
-
تؤدي الواجهة (Facade) والوسيط (Mediator) وظائف متشابهة: كلاهما يحاول تنظيم التعاون بين فئات كثيرة مترابطة بإحكام.
- تُعرّف الواجهة واجهة مبسطة لنظام فرعي من الكائنات، لكنها لا تُدخل أي وظائف جديدة. النظام الفرعي نفسه لا يعرف بوجود الواجهة. يمكن للكائنات داخل النظام الفرعي التواصل مباشرة مع بعضها.
- يُمركز الوسيط التواصل بين مكوّنات النظام. المكوّنات تعرف فقط كائن الوسيط ولا تتواصل مباشرة.
-
يمكن في أغلب الأحيان تحويل فئة الواجهة (Facade) إلى المفرد (Singleton) نظرًا لأن كائن واجهة واحدًا يكفي في معظم الحالات.
-
تتشابه الواجهة (Facade) مع الوكيل (Proxy) في أن كليهما يُضيف طبقة حاجزة أمام كيان معقد ويُهيئه بشكل مستقل. على عكس الواجهة، يمتلك الوكيل نفس الواجهة التي يمتلكها كائن الخدمة، مما يجعلهما قابلَين للتبادل.