Façade Pattern الهدف : يؤمن واجهة موحدة لمجموعة من الواجهات في نظام جزئي .إنه يعّرف واجهة عالية – المستوى تجعل النظام الجزئي أسهل للستخدام . الدراسة : إن تجزيء النظام إلى أنظمة جزيئة يساعد على تقليل التعقيد .إن هدف التصميم العام هو تصغير التصال والعتماديات بين النظمة الجزئية إلى أقل قدر ممكن .وإحدى الطرق لتحقيق هذا الهدف هي تقديم الغرض façadeالذي يؤمن واجهة وحيدة ،مبسطة تجعل النظام الجزئي أسهل عموما ً .
افترض كمثال بيئة برمجية التي تتيح الوصول إلى التطبيقات إلى نظام الـ Compilerالخاص بها ) الذي يعتر هنا نظام جزئي subsystemمن البيئة ( .هذا النظام الجزئي يحوي صفوف مثل : scanner ، Parser ، ProgramNode ، BytecodeStream ، ProgramNodeBuilderالذي يحقق الـ . Compiler بعض التطبيقات المخصصة قد تحتاجج إلى الولوج إلى تلك الصفوف مباشرة .ولكن معظم زبائن الـ compilerعموما ل يهتمون تفاصيل مثل تحليل وتوليد ، codeبل يريدون ترجمة بعض .codeبالنسبة لهم ،والمستوى المنخفض قوية ولكن واجهات في النظام الـ compilerالجزئي ال الى تعقيد مهمتها. لكي تؤمن واجهة عالية المستوى تستطيع حجب الزبائن عن هذه الصفوف ،فإن نظام الـ Compilerالجزئي يتضمن أيضا ً صف . Compilerهذا الصف يعرف واجهة موحدة لوظيفة الـ .Compiler ان صف Compilerيعرف بالـ : façadeيوفر للزبائن واجهة بسيطة ،وحيدة لنظام الـ compilerالجزئي .لدمج الصفوف التي تحقق وظيفية الـ compilerمع بعضها بدون أن يخفيها تماما ً . ان الـ compiler façadeيجعل الحياة أسهل لمعظم المبرمجين بدون اخفاء الوظيفية ذات المستوى الخفض التي قد يحتاجون إليها قليل ً .
1
Façade Pattern
التطبيق :استخدام الـ façade patternعندما : •تريد أن تؤمن واجهة بسيطة لنظام جزئي معقد .بعض النظمة الجزئية غالبا ً تأخذ تعقيد أكثر وقت انشائها .معظم الـ ، patternsعند تطبيقها ،تولد صفوف أكثر وأصغر .هذا يجعل النظام الجزئي أكثر قابلية لعادة الستخدام وأسهل للتخصيص ،ولكن يصبح أيضا ً أصعب للستخدام من قبل الزبائن الذين ل يحتاجون إلى تخصيصه .يستطيع façade تأمين منظر افتراضي بسيط للنظام الجزئي جيد كفاية لمعظم الزبائن .فقط الزبائن المحتاجين لخصوصية أكثر سيحتاجون للنظر خلف الـ . façade •هناك العديد من العتماديات بين الزبائن وصفوف تحقيق التجريد .استخدام الـ façade التي تفصل النظام الجزئي عن الزبائن والنظمة الجزئية الخرى ،إنذلك يعزز استقللية وناقلية النظام الجزئي . •عندما تريد أن تجعل نظامك الجزئي من طبقات .استخدم الـ façadeلتعّرف نقطة دخول لكل مستوى من مستويات النظام الجزئي .إذا كانت النظمة الجزئية معتمدة على بعضها ،فعند ذلك تستطيع أن تبسط العتماديات بينها بجعلها تتصل فيمابينها ببطء عبر الـ façadeالخاصة بكل منها. البنية :
2
Façade Pattern القسام : •: ( Façade ( compiler -1يعرف أي من صفوف النظام الجزئي ستكوةن مسؤولة عن الطلب . وض طلبات الزبون إلى أغراض النظام الجزئي المناسبة. -2يف ّ •: (.subsystem classes (Scanner, Parser, ProgramNode, etc -1تحقق وظيفية النظام الجزئي. -2تعالج العمل المخصص لها من قبل الغرض . façade -3ل تملك أي معرفة بالـ ، façadeبما معناه :ل تبقي أي مؤشرات إليه . أسلوب العمل : •الربائن يتصلون بالنظام الجزئي عن طريق إرسال الطلبات إلى الـ ، façadeالذي بدوره يرسلهم إلى غرض )أغراض (النظام الجزئي المناسب .بالرغم من أن أغراض النظام الجزئي تحقق العمل الفعلي ،فقد يضطر الـ façadeإلى إنجاز العمل للنظام الجزئي الخاص به لكي يترجم واجهته إلى واجهات النظام الجزئي . •الربائن الذي يستخدمون الـ façadeل يحتاجون إلى الولوج لغراض نظامه الجزئي مباشرة . النتائج : دم الـ façade patternالمنافع التالية : يق ّ -1إنه يحجب الزبائن عن مكونات النظام الجزئي ،هذا يعني تقليل عدد الغراض التي يتعامل الزبائن معها وجعل النظام الجزئي أسهل للستخدام . ً -2انه يعزز الرتباط الضعيف بين النظام الجزئي و زبائنه .غالبا فإن مكونات النظام الجزئي تكون مرتبطه بقوة .الرتباط الضعيف يدعك تغير مكونات النظام الجزئي بدون التأثير على زبائنه .الـ façadeتساعد على عمل العتماديات بين الغراض والنظام كطبقات . انها تستطيع التخلص من العتماديات المعقدة أو الدورية .إن ذلك يمكن أن يكون نتيجة هامة عندما تكون الزبائن و النظام الجزئي محققة بشكل منفصل . -3تقليل اعتماديات الترجمة يعتبر أساسيات في أنظمة الـ softwareالضخمة .أنت تريد حفظ الوقت بتقليل إعادة الترجمة بأكبر قدر ممكن عندما تتغير صفوف النظام الجزئي . إن تقليل اعتماديات الترجمة باستخدام façadeيستطيع حد إعادة الترجمة المطلوة من أجل تغير صغير في نظام جزئي هام .ستطيع الـ façadeأيضا ً بتبسيط أنظمة النفوذ إلى منصات عمل أخرى ،لنه لسوء الحظ فإن بناء نظام جزئي واحد يتطلب بناء كل النظمة الجزئية الخرى . -4إنه ل يمنع التطبيقات من استخدام صفوف النظام الجزئي إذا احتاجت لها .وبالتالي يمكنك أن تختار بين سهولة الستخدام والتعميم . التحقيق : يجب النتباه غلى القضايا التالية عن تطبيق الـ : façade -1تقليل الرتباط : client – subsystem الرتباط بين الزبائن و النظام الجزئي يمكن أن يقلل بجعل الـ façadeكـ abstract classمع صفوف جزئية محددة من أجل التطبيقات للنظام الجزئي .عندئذ يستطيع الزبائن التصال مع النظام الجزئي عبر واجهة صف façadeالمجرد .هذا الرتباط 3
Façade Pattern المجرد يجعل الزبائن ليعلمون أي تطبيق للنظام الجزئي تم استخدامة .وهو إحدى الحلول . كبديل عن الصفوف الجزئية يمكن اعداد الغرض الـ façadeمع أغراض مختلفة من النظام الجزئي .كي تخصص الـ ، façadeاستبدال ببساطة واحد أو أكثر من أغراض نظامه الجزئي. -2الموازنة بين صفوف النظام الجزئي الـ : private & public النظام الجزئي هو تمثل لصف هذا الصف يملك واجهات و يغلف شيئا ً ما – الصف يغلف " حالة وعمليات "بينما النظام الجزئي يغلف صفوف .وتماما كما أنه من المفيد أن نفكر بواجهة publicو privateلصف ،نستطيع أن نفكر بواجهة publicو privateللظام الجزئي الواجهة الـ publicللنظام الجزئي تتألف من صفوف تستطيع كل الزبائن ولوجها . أما الواجهة الـ privateفهي فقط من أجل الربائن الذين يتوسعون باستخدام النظام الجزئي . الصف façadeهو جز من الواجهة الـ publicبالطبع ،ولكنه ليس الجزء الوحيد . صفوف النظام الجزئي الخرى هي أيضا ً . publicكمثال :الصفوف Scanner, Parser في نظام الـ compilerالجزئي يعتبر أن جزء من الواجهة الـ . public –ان جعل صفوف النظام الجزئي privateسيكون نافعا ً ،ولكن القليل من اللغات الغرضية التوجة تدعم تلك الصفوف .كل من الـ ++Cوالـ smalltalkتقليديا ً امتلكتا فضاء تسمية globalمن أجل الصفوف . : Sample code دعنا نلقي نظرة قريبة عن كيفية اضافة façadeإلى نظام الـ compilerالجزئي : –انت نظام الـ Compilerالجزئي يعرف صف ) ( BytecodeStreamيحقق مجرى من أغراض . Bytecodeالغرض Bytecodeيغلف bytecodeالذي يستطيع تحديد تعليمات اللة . ً –النظام الجزئي يعرف أيضا الصف Tokenمن أجل الغراض التي تغلف الـ token في لغة البرمجة –الصف Scannerيأخذ مجرى من المحارف ويولد مجرى من الـ tokens ،token واحدة بالثانية . { class Scanner public: ;)&Scanner(istream ;)(virtual ~Scanner ;)(virtual Token& Scan private: ;istream& _inputStream ;}
الصف parserيستخدم ProgramNodeBuilderليبني شجرة parseمن الـ Scanner's tokens
{ class Parser public: ;)(Parser ;)(virtual ~Parser
4
Façade Pattern
};
virtual void Parse(Scanner&, ProgramNodeBuilder&);
بتزايدparse ليبني شجرةProgramNodeBuilder من جديدparser يستدعي the Builder pattern هذه الصفوف تخضع للـ class ProgramNodeBuilder { public: ProgramNodeBuilder(); virtual ProgramNode* NewVariable( const char* variableName ) const; virtual ProgramNode* NewAssignment( ProgramNode* variable, ProgramNode* expression ) const; virtual ProgramNode* NewReturnStatement( ProgramNode* value ) const; virtual ProgramNode* NewCondition( ProgramNode* condition, ProgramNode* truePart, ProgramNode* falsePart ) const; // ...
: مثلStatementNode, ExpressionNode من مثائل منparse tree تم صنع الـ Composite pattern : هي مثال عنProgramNode إن هرمية. الخ... ProgramNode class ProgramNode { public: // program node manipulation virtual void GetSourcePosition(int& line, int& index); // ... // child manipulation virtual void Add(ProgramNode*); virtual void Remove(ProgramNode*); // ... virtual void Traverse(CodeGenerator&); protected: ProgramNode(); };
ProgramNode subclasses الـ، CodeGenerator تأخذ غرضTraverse operation الـ BytecodeStream على الـBytecode تستخدم ذلك الغرض لتوليد كود آلة بصيغة أغراض visitor هوCodeGenerator الصف class CodeGenerator { public: virtual void Visit(StatementNode*); virtual void Visit(ExpressionNode*); // ...
5
Façade Pattern protected: CodeGenerator(BytecodeStream&); protected: BytecodeStream& _output; };
void ExpressionNode::Traverse (CodeGenerator& cg) { cg.Visit(this); ListIterator i(_children); for (i.First(); !i.IsDone(); i.Next()) { i.CurrentItem()->Traverse(cg); } }
سنقدم الصف، ال. Subsystem compiler الصفوف التي ناقشناها حتى الن تصنع الـ . الذي يجمع كل تلك القطع مع بعضهاFaçade أيCompiler class Compiler { public: Compiler(); };
virtual void Compile(istream&, BytecodeStream&);
void Compiler::Compile ( istream& input, BytecodeStream& output ) { Scanner scanner(input); ProgramNodeBuilder builder; Parser parser; parser.Parse(scanner, builder);
}
RISCCodeGenerator generator(output); ProgramNode* parseTree = builder.GetRootNode(); parseTree->Traverse(generator);
. مز نوع مولد الكود ليستخدم بحيث ل يتم طلب مبرمجين ليحددوا البينية الهدف ّ هذا التحقيق ير عند ذلك قد يزيد، إذا لم يكن كذلك. قد يكون ذلك ممقول ً إذا كان هناك فقط بينية هدف واحدة عند ذلك يستطيع المبرمجون تحديدCodeGenerator ليأخذ البرامتيرCompiler تغيير باني الـ Compiler المولد ليتم استخدامه عندما يجهزون الـ وscanner إضافة مشاركين أخر بين مثلcompiler façade يستطيع الـ façade ولكنه أيضا ً سيقلل من مهمة الـ، الذي يضيف المرونة، programNodeBuilder . التي تتمثل بتبسيط الواجهة من أجل الحالة العامةpattern العلقة 6
Façade Pattern Abstract Factory.1 يمكن أن يستخدم مع façadeليؤمن واجهة لعمل أغراض النظام الجزئي في طريقة subsystem-independentويمكن أن يستخدم أيضا ً كبديل عن الـ façadeلخفاء الصفوف المخصصة لمنصة العمل . Mediator.2 يشابه الـ façadeمن حيث أنه يجرد وظيفية الصفوف الموجودة تجريد التصال التحكمي بين الغراض المتراصفة وتكون عادة الوظيفية المركزية لتنتمي لي من هذه الغراض هذه الغراض تتصل بالـ mediatorبدل ً من اتصالها ببعضها البعض مباشرة.
بشكل عام يجرد الـ façadeالواجهة لغراض النظام الجزئي لجعلهم أسهل للستخدام ،انه ل يعرف وظيفة جديدة ،وصفوف النظام الجزئي ل تعلم شيئا ً عنها . عادة ،يطلب فقط غرض façadeواحد فإن الـ façade objectتكون عادة singletons
7