شطيرة اللحم البقري "الهامبرجر Hamburger" (أو كما ينطق إسمها الكثير من العرب هامبرجل) تعتبر –في رأي الشخصي- ابرز رمز صارخ للعولمة Globalization التي تواجهها المجتمعات المدنية، فوجوده أصبح في كل مكان وزمان (في الإفطار، الغداء، العشاء، وأي وجبات جانبية أخرى)، لدرجة أنا لا نعلم من هم أكثر شعوب الأرض استهلاكا له، هل هم الشرق أم الغرب؟! ولكن (وبغض النظر عن كافة الاعتبارات العرفية الأخرى) أرى فيه مثال تجسيدي رائع لمبدأ الطبقات Tiers وكيف يمكن أن تزيد من إنتاجية بناء وجبات الهامبرجر وكافة السندويتشات التي تتخذ منحناه.
في الصورة المغرية السابقة، تبدأ الطبقة العلوية Upper Tie بقطعة من الخبز التي تمثل الواجهة العلوية والمغلفة للساندويتش وهي نفس الطبقة السفلية، ومن ثم طبقة تحتوي على تشكيلة متنوعة من الخضروات Vegetable Tier، وبعدها الطبقة الرئيسية (طبقة شريحة اللحم Meat Tier) وهي أهم ما في الوجود (المحرك الأساسي للنظام Core Engine) والتي قال فيها أحد الشعراء:
أمر على الديار ديار لحم ... أقلب ذا الغطـاء وذا الغطـاء
وما حب القدور شغفن قلبي ... ولكن حب من سكن الوعاء
كيف يمكن أن تفيدنا طبقات الهامبرجر
إن عملية بناء الهامبرجر بهذا الشكل لها فوائد جمة لا حصر لها، أول فائدة أراها من منظور التخصص Specialization لزيادة الجودة Quality، فهناك خباز له خبرة عشرات السنين في التعامل مع الدقيق لصناعة الخبز، ويمكننا ان نعتمد عليه في بناء خبز وجبتنا، ومن ناحية الخضروات، فقد نعتمد على أحد المراكز التي تعرض أنقى وأفضل أنواع الخضراوات الطازجة، كذلك الحال مع طبقة اللحم، يمكننا أن نتعامل مع مطبخ يأتي يوميا بلحوم طازجة ذبحت للتو، وبذلك تزيد الجودة Quality للمنتج بشكل خرافي بسبب تخصص كل شخص في بناء الطبقة المناسبة، ويبقى علينا تجميع الطبقات ومن ثم بيعها للمستخدم النهائي (أقصد الزبون).
كان هذا من ناحية البناء Construction وأريد أن أتحدث هنا عن التنقيح Debugging او التعديل، فعندما نريد (مثلا) تطوير نسخة أخرى من الهامبرجر (نسخة خفيفة Light Edition) لأشخاص يتبعون حمية غذائية خاصة، فكل ما سنفعله تغيير طبقة الخبز Bread Tier لتعتمد على خبز بر (خبز أسمر Brown Bread)، دون تحمل أي تكلفة لتعديل الطبقات الأخرى (ولا أعلم من هو ذلك الشخص الذي يتبع حمية غذائية ويستمر على أكل الهامبرجر!).
وعندما نفكر في التدويل Internationalization وأخذ الإعدادات الإقليمية Localizations بعين الاعتبار، فالمسألة لن تتعدى طبقة اللحم Meat Tier، فاليهود لا يأكلون لحوم الخنزير أو زيوت من مشتقاته، ويزيدهم على ذلك المسلمون أيضا، فلابد أن تكون طريقة ذبح اللحم حلال Halal، وعند الهندوز فلا يمكن أن يكون لحم بقري (فهو محرم أكلها بعقيدتهم)، كل ما نحتاجه تعديل في طبقة اللحم فقط، وتبقى عقود الموردين Vendors (الذين نتعامل معهم) للطبقات الأخرى كما هي دون مشاكل.
ميزة أخرى قد نحتاجها بعد فترة من الإنتاج، وهي عند ظهور شوائب Bugs او أخطاء في هذا المنتج، فيمكن إصلاح المشكلة في الطبقة التي ينتمي لها ((فقط)) دون ان تتأثر ودون أن نحتاج الى تعديل الطبقات الاخرى.
ماذا لو ؟!
أريدك للحظة ان تتخيل الهامبرجر دون طبقات كما في هذه الصورة:
فهنا أي تعديل او تطوير او صيانة ستستهلك جهد ووقت اضافي (إن لم تكن مستحيلة)، بل سنحتاج الى اعادة البناء من جديد عند التعديلات الجوهرية، وكل المزايا التي عرضناها بالفقرات السابقة واختصار الوقت وتوفير الاموال (خاصة التي مع تعاقدات الموردين Vendors) لا يمكن تطبيقها هنا -أي كل تغيير بسيط بحاجة الى تعديل جديد للمنتج.
بعيدا عن الهامبرجر
يقال أنه توجد علاقة عكسية بين عمل العقل وعمل المعدة، فعندما تعمل المعدة يتعطل العقل، وبما أني بحاجة ماسة لاستهلاك كل طاقة عقلك الإنتاجية، فسأتوقف هنا عن عروض الهامبرجر وأحاول ان أعرف التطبيقات المتعددة الطبقات N-Tier Applications والتي ليست سوى أسلوب لتصميم معماري Architecture Design يهدف الى تقسيم التطبيق الى طبقات مستقلة، تقوم كل طبقة بأداء مهمة ووظيفة ((محددة)) و ((واضحة)). مع التنويه بأن هذه الطبقات يمكن ان تعمل في نفس منصة العمل Platform او منصات عمل مختلفة –أي يمكن ان تعمل هذه الطبقات المختلفة في جهاز شخصي واحد او عشرين ألف جهاز خادم Server (فهو تصميم نظري Conceptual وليس فيزيائي Physical).
مزايا/عيوب التصميم متعدد الطبقات
مثل هذه الفقرة يصعب جدا التعميم معها، ولكن سأحاول عرض ابرز المزايا والعيوب بشكل مبسط ومختصر:
المزايا:
• تجعل البرنامج اكثر تنظيما وتخفض تكلفة تعقيدات البرامج Software Complexity مما تسهل عملية بنائها وتقل مخاطر Risks فشل المشروع.
• يمكنك تعديل أي طبقة وتصحيح مشاكلها او تطويرها دون تغيير او تعديل الطبقات الاخرى.
• يمكنك اضافة طبقات جديدة دون مجهود.
• التطبيقات المعدة بهذا التصميم دائما ما تكون أكثر أمانا (فالثغرات الأمنية بها قليلة جدا).
• إعادة الاستخدام Code Reusability، يمكنك تصميم طبقاتك بطرق احترافية حتى تتمكن من إعادة استخدامها في مشاريع اخرى.
• مناسبة جدا للعمل الجماعي وفرق التطوير، حيث توضح مهام كل عضو بدقة ووضوح.
العيوب:
• تتطلب كتابة الكثير من الاكواد.
•التوثيق Documentation يصبح أمر إلزامي خاصة إن كبر حجم وكثر عدد الطبقات.
• بحاجة الى مجهود لضمان نجاح الاتصالات بين الطبقات المختلفة.
• التكرار في كتابة بعض الاكواد (خاصة اكواد القوانين Rules) في اكثر من طبقة.
التصميم ثلاثي الطبقات
قلنا أن التصميم متعدد الطبقات يقسم التطبيقات الى طبقات مستقلة، وإن سألتني (أو لم تسألني) كم العدد الصحيح لهذه الطبقات؟ فالإجابة تبدأ من 2 إلى أقصى عدد يمكن أن تتحمله أناملك، ولكن التصميم ثلاثي الطبقات 3Tier Design يعتبر الأشهر والأكثر إتباعا:
كما في الشكل السابق، يقسم التصميم ثلاثي الطبقات برنامجك الى 3 طبقات منفصلة:
• طبقة العرض View Tier: تمثل طبقة العرض واجهة الاستخدام User Interface الرئيسية للبرنامج، والتي تكون بالعادة إما تطبيق Windows Application أو موقع Web Application، وهي تحتوي على جميع الأجزاء المرئية التي تستخدم لتنفيذ الوظائف والأوامر المختلفة للتطبيق.
• طبقة الأعمال Business Tier: تمثل طبقة الأعمال (تسمى أيضا بمنطق الأعمال Business Logic) الانجاز الفعلي Real Implementation لجميع الوظائف والأوامر التي يقوم بها التطبيق، وقد تشمل أيضا القواعد والقوانين Rules الخاصة ببرنامجك. الغالبية الساحقة من هذه الطبقات تكون على شكل مكتبة فئات Class Library في ملفات DLL.
• طبقة البيانات Data Tier: طبقة البيانات هي الطبقة المسئولة عن حفظ وتخزين كافة وحدات التطبيق Application Entities، يمكن لعملية الحفظ أن تكون في ملفات على القرص او في مسجل النظام System Registry. وإن زادت البيانات وأردت سرعة ومرونة في التعامل معها بلا حدود، فلن تجد أفضل من الاعتماد على خادم قواعد بيانات DBMS (Microsoft SQL Server 2005 اختياري المفضل دائما).
من المهم جدا جدا جدا جدا (ما أكثر استخدامي لهذا التعبير في جميع كتاباتي) أن تتم عملية الاتصال بين الطبقات بشكل نظامي وليس عشوائي، بمعنى أن طبقة العرض -مثلا- ممنوعة منعا باتا من التحدث مع طبقة البيانات، فطبقة العرض لا تعلم أي شيء عن البيانات ولا تدري ماذا يحدث بها ومن هو المسئول عنها، فهي تعرف كيف تتحدث مع طبقة الأعمال فقط (والتي تكون متفهمة مع طبقة البيانات).
إن ضربت بتحذيري عرض الحائط، فاعلم أنك تخلط الحابل بالنابل، وتسمح لطبقاتك بتكوين علاقات غير شرعية ستؤدي الى كوارث في تصميمك الثلاثي الطبقات، والتي قد تكون مصيبتها أكبر من شوائب Bugs (قد تؤدي الى ثغرات أمنية Security Hacks).
أخيرا، الطبقات هذه في تطور مستمر ويمكنك إضافة طبقات أخرى متى ما دعت الحاجة إلى ذلك، فموقعي المتواضع al-asiri.COM (الذي يعتمد التصميم ثلاثي الطبقات) أستطيع أن أضيف عليه طبقة جديدة لخدمة ويب Web-Service أو أستخدم مولد تقارير لقاعدة البيانات دون الحاجة الى تعديل ((حرف واحد)) من الطبقات الأخرى والنظام الأساسي للموقع:
مشروعنا
الحديث عن التصميم متعدد الطبقات حديث ذو شجون وقد ألف فيه مئات الكتب وكتب عنه آلاف المقالات، وكان غرضي الحقيقي في هذا المقال تعريفه للمبتدئين فقط، ومن هنا سأكتفي بما سطرته من الكلام النظري،ونبدأ في ورشة عمل صغيرة، وهي عبارة عن مشروع بسيط جدا جدا (قد يطوره الأطفال) يهدف الى تطوير برنامج يتبع اسلوب التصميم ثلاثي الطبقات.
برنامجنا الصغير فكرته تحتك بشكل مباشر مع ما استفتحت به هذا المقال (الهامبرجر)، حيث يقوم بتسجيل طلبات الزبائن لصاحب مطعم، وينقسم الى ثلاث طبقات:
طبقة العرض ستكون تطبيق Windows Application، وطبقة الأعمال ستكون مجموعة من الفئات Classes محضونة داخل مكتبة DLL وطبقة البيانات ستعتمد على خادمي المفضل Microsoft SQL Server 2005.
في هذا المقال سننجز طبقة البيانات فقط. والطبقات الأخرى في المقال/المقالات القادمـ/ـة (قد يكون واحد او اثنين، على حسب المزاج!)
طبقة البيانات
وهي كل ما يتعلق بقاعدة البيانات، وفي مشروعنا البسيط تنقسم الى قسمين: الأول الجداول Tables والقسم الثاني إجراءات Stored Procedures، بالنسبة للجداول فالشكل التالي يختصر كل الحكاية:
في التطبيقات الكبيرة والمحترمة (وليس مثل مشروعنا) يتم التخطيط أولا (قبل البدء في تصميم قاعدة البيانات) بإتباع مخططات وحدات العلاقات Entity Relationship Diagrams (ER-Diagrams)، والتي ليست سوى رسوم لتصميم عالي المستوى High Level Design لقاعدة البيانات. أنصحك بالبحث حول هذا الموضوع في أي موقع بحث.
بخصوص إجراءات Stored Procedures فهناك 4 إجراءات خاصة بجدول المنتجات Products، الاجراء Products.AddNew مثلا غرضه تعريف منتج جديد في الجدول:
ALTER PROCEDURE [Products.AddNew]
(
@prdID uniqueidentifier,
@prdName nvarchar(50)
)
AS
SET NOCOUNT ON
INSERT INTO Products
(
prdID,
prdName
)
VALUES
(
@prdID,
@prdName
)
RETURN
الاجراء Products.GetAll يعود بكافة المنتجات، والاجراء Products.Update لتعديل سجل، والاجراء Products.Delete واضح غرضه. بالنسبة لجدول الطلبات Orders ووحدات الطلبات Items فتكون البداية مع الاجراء Orders.DefineNewOrder والذي يبدأ بإنشاء سجل جديد في جدول Orders ليمثل طلب جديد:
ALTER PROCEDURE [Orders.DefineNewOrder]
(
@ordID uniqueidentifier,
@ordDate smalldatetime
)
AS
SET NOCOUNT ON
INSERT INTO Orders
(
ordID,
ordDate
)
VALUES
(
@ordID,
@ordDate
)
RETURN
وفي كل مرة تود اضافة عنصر الى الطلب، فالاجراء Orders.AddItemToOrder تحت الخدمة:
ALTER PROCEDURE [Orders.AddItemToOrder]
(
@itmOrderID uniqueidentifier,
@itmProductID uniqueidentifier,
@itmQuantity smallint
)
AS
SET NOCOUNT ON
INSERT INTO Items
(
itmOrderID,
itmProductID,
itmQuantity
)
VALUES
(
@itmOrderID,
@itmProductID,
@itmQuantity
)
RETURN
الاجراء Orders.RemoveItemFromOrder يحذف احد العناصر من الطلب، ويمكنك معرفة جميع العناصر التابعة للطلب من خلال الاجراء Orders.GetAllItemInOrder. أخيرا، بالنسبة للاجراء Orders.DeleteOrder سيقوم بحذف الطلب وجميع العناصر التابعة له في جدول Items:
ALTER PROCEDURE [Orders.DeleteOrder]
(
@ordID uniqueidentifier
)
AS
SET NOCOUNT ON
DELETE FROM
Orders
WHERE
ordID = @ordID
DELETE FROM
Items
WHERE
itmOrderID = @ordID
RETURN
قد تتساءل عن سبب قيامي بحذف العناصر (في جدول Items) يدويا، فالمتوقع ان يقوم محرك قاعدة البيانات بحذفها تلقائيا بسبب العلاقة، ولكن في الحقيقة لا توجد علاقات بين الجداول فلا أحبذ استخدامها كثيرا بسبب أنها تضعف كفاءة التنفيذ، وبالنسبة للعلاقات الواضحة بالصورة فهي للتوضيح فقط (كما يقول المثل: لا تصدق كل ما تراه).
خاتمة
التطبيقات متعددة الطبقات N-Tier Applications ليست سوى أسلوب لتصميم معماري Architecture Design يتبعه مصممو التطبيقات، الغرض منه تقسيم التطبيق إلى طبقات مستقلة أكثر تنظيما وقابلية للصيانة. في المقال القادم سنكمل ورشة العمل لبناء تطبيق ثلاثي الطبقات، والى ذلك الحين يمكنك إنزال شفرة قاعدة البيانات Database Script (استخدم حفظ باسم Save As افضل لك) شاملة للجداول وإجراءات Stored Procedures التي صممناها للتو.
-- تركي