SyntaxHighlighter

الثلاثاء، 21 يونيو 2011

مايكروسوفت والمصادر المفتوحة Open Source في مصر. عدو أم شريك!

كنت أتمنى حضور مناقشات ملتقى الاستراتيجية المصرية للمصادر المفتوحة لولا وجودي خارج مصر فهدف انتقالنا من خانة مستهلكي التكنولوجيا إلى مقاعد القيادة والإنتاج المعرفي هو أمل يقترب إلى التحقق يوما بعد يوم واستراتيجية واضحة للمصادر المفتوحة خطوة مهمة في هذا الطريق. لاحظت من متابعتي للمشاركين لهجة عدائية لمايكروسوفت باعتبارها نقيض لمبادئ المصادر المفتوحة ورمز للشر. قبل الدخول في مناقشات واستنتاجات سواء تأييدا أو دفاعا عن وجهة النظر هذه أود سرد لبعض الوقائع
- مايكروسوفت بدأت بكتابة بول ألان وبيل جيتس لمترجم للغة البيزيك عام 1975 وهي لغة طورها جون كيميني وتوماس كورتز وعلى حد علمي لم تشتري مايكروسوفت حقوقا للملكية بل استفادت من كونها مشاعا.
- كانت الطفرة والانطلاقة لمايكروسوفت هي شراكتها مع IBM ولكن كعملاق يتعامل مع شركة متناهية في الصغر لم تحصل مايكروسوفت على الكثير من صفقتها مع IBM ولكن أرباحها جاءت مع ظهور سوق الأجهزة المتوافقة التي ظهرت بحيلة قانونية قامت بها شركة كومباك Compaq حيث أن جميع مكونات الحاسب الشخصي كانت متاحة في الأسواق فيما عدا BIOS فاستأجرت فريق قام بهندسة عكسية له وكتابة مواصفة كاملة له وفريق آخر منفصل بإنتاج BIOS متوافق بناء على هذه المواصفات وهنا ظهر هذا السوق بالتحايل على حقوق الملكية الفكرية واستفادت مايكروسوفت ببيع نظام تشغيلها على هذه الأجهزة.
- كانت الحواسيب الشخصية بمثابة لعبة للهواة إلى أن كتب دان بريكلين تطبيق VisiCalc أول تطبيقات الجداول الممتدة Spreadsheets والذي أظهر قدرة هذه الأجهزة في مجال الأعمال. ولم يقم دان بتسجيل براءة للاختراع وظهرت برامج كثيرة معتمدة على فكرته منها تطبيق إكسيل Excel الأشهر من مايكروسوفت. وحاليا لا يزال دان يكتب التطبيقات وخاصة لأجهزة iPad.
- شعرت شركة زيروكس بتهديد من التقنيات الإلكترونية الجديدة على سوقها المعتمد أساسا على التعاملات الورقية فاستقدمت مجموعة من أمهر الباحثين في مختبرها في بالو ألتو لتصور ما ستكون عليه مكاتب المستقبل. من هذا المختبر خرج كم هائل من التقنيات التي تؤثر في حياتنا ومن أهمها تقنية واجهات الاستخدام الرسومية GUI. حيث دعا القائمين على هذا المختبر ستيف جوبز مؤسس شركة أبل للتجول وإلقاء نظرة على الأبحاث وخرج جوبز من هذه الجولة بفكرة واحدة هي تطوير نظام تشغيل يعتمد على الواجهات الرسومية وبالطبع دون دفع ثمن حقوق ملكية لزيروكس وتلته مايكروسوفت في تطوير نظام تشغيلها الأشهر ويندوز.
هناك العديد من الأمثلة التاريخية ولكن سأكتفي بما ذكرته فمما سبق يمكن استنتاج أن الشركات الكبيرة ومنها مايكروسوفت استفادت بشكل كبير من حرية تداول المعلومات ومن أفكار الآخرين وأننا لم نكن لنصل لما نحن عليه الآن بدون هذا التداول. إلا أن الشركات كانت تستفيد من هذه الحرية ثم تغلق الباب على ما تضيفه من أفكار وكان هذا جليا في حالة نظام التشغيل يونكس مما حفز ريتشارد ستالمان على تكوين نظام آخر يعتمد على حرية تداول الأفكار كأساس ومن هذا المنطلق ولدت فكرة البرمجيات الحرة و GPL. وسطع نجم البرمجيات الحرة مع ظهور لينوكس كبديل قوي وفعال لأنظمة التشغيل التجارية خاصة كمنصة للخوادم. وكان موقف مايكروسوفت حاد مع فكرة المصادر المفتوحة وظهر هذا في التصريحات التالية
- بيل جيتس يصف مطوري المصادر المفتوحة بالشيوعيين الجدد في عام 2005 ,ان كل من يحاول وضع قيود على حقوق الملكية الفكرية هو شيوعي
- في عام 2001 وصف ستيف بالمر لينوكس وترخيص GPL كالسرطان الذي يتغذى على الملكية الفكرية ويقضى على حرية الاختيار بين البرمجيات الحرة المجانية والتجارية.
يتضح بجلاء موقف مايكروسوفت منذ مدة ليست بالبعيدة من البرمجيات الحرة والتي بجانب التصريحات كانت تتمثل بممارسات أخرى منها قيود مشددة بمنع أي من مطوري مايكروسوفت بالعمل على تطبيقات مفتوحة المصدر حتى خارج أوقات العمل. ولكن تدريجيا بدأت ثقافة جديدة بالظهور تتضح بالأمثلة التالية
- في عام 2004 روب مانشينج ينشر مشروع Wix على SourceForge كأول مشروع مفتوح المصدر يخرج من مايكروسوفت على الرغم أنه كان يعمل عليه في أوقات فراغه إلا أن دافعه كان اعتقاده بأن الكثير ممن داخل مايكروسوفت لا يفهمون المصادر المفتوحة مما شجعه على أن يعمل على نشر هذه الثقافة بمثال عملي.
- عام 2006 افتتحت مايكروسوفت موقع CodePlex لاستضافة التطبيقات المفتوحة المصدر سواء لمشاريع من مايكروسوفت أو من مجتمع المطورين.
- أنشأت مايكروسوفت مؤسسة OutCurve لمساعدة المؤسسات على تبني التقنيات المفتوحة المصدر حيث تتبنى المؤسسة بعض المشاريع وتضمن عدم التوقف عن العمل فيها ودعمها بالإضافة للتمحيص القانوني لحماية مستخدمي التقنيات.
- تبرعت مايكروسوفت ببعض الكود لنواة لينوكس وعلى الرغم أن هذا الكود يهدف إلى تحسين أداء لينوكس عند العمل على نظام Hyper-V إلا أنها كانت المرة الأولى التي تقوم بها مايكروسوفت بالدخول في منظومة البرمجيات الحرة التقليدية وعالم اللينوكس.
- أصدرت مايكروسوفت مشروع NuGet لتسهيل عملية استيراد واستخدام المكونات المفتوحة المصدر بالإضافة أنه أول مشروع تقبل فيه مايكروسوفت بمشاركات من خارج موظفيها.
- أصدرت مايكروسوفت مشروع WebMatrix كتطبيق مجاني والذي يسهل بشكل كبير تطوير تطبيقات ويب معتمدة على نظم مفتوحة المصدر ويدعم بشكل قوي التطبيقات المكتوبة بلغة PHP.
هناك أمثلة أخرى كثيرة لتغير استراتيجية مايكروسوفت تجاه البرمجيات الحرة ولكن لن أذهب بالاستنتاج بأن مايكروسوفت قد تحولت إلى الملاك البريء المحب للحرية فهي في النهاية شركة رأسمالية ولائها الأساسي للربح والمستثمرين فعلى سبيل المثال أوقفت تمويل مشاريع IronPython و IronRuby لأنهم يمثلوا مدخل سهل للانتقال من منصة ويندوز إلى منصة لينوكس. إلا أن رأيي الشخصي أن هناك مساحة كبيرة للتفاوض والضغط لتكون مايكروسوفت شريكا فاعلا في الاستراتيجية المصرية للمصادر المفتوحة. ولكن ما الفائدة التي يمكن أن تقدمها مايكروسوفت وما الضامن لأن تصب العلاقة في صالح مجتمع المعلومات المصري؟
استثمرت مايكروسوفت بشكل كبير في العلاقة مع المؤسسات التعليمية ولديها شبكة قوية من الطلاب تحت برنامج MSP ومسابقة كأس التخيل Imagine Cup إلا أن غياب المنافسة أدى إلى سيادة الولاء للشركة أكثر من الجودة والانفتاح على التقنيات المختلفة سواء من داخل منظومة مايكروسوفت أو خارجها. ولكن بتكوين شراكة بين مايكروسوفت ومجتمع البرمجيات الحرة سيستفيد المجتمع من شبكة العلاقات وإمكانيات الوصول الأسهل لقاعدة الطلاب وتستفيد مايكروسوفت من تحسين جودة المطورين وبالرغم من أنها قد تخسر بعض المطورين لمنصات أخرى إلا أنها ستكسب مصداقية وجودة من عدد أكبر يعوض هذه الهجرة بدلا من المخاطرة بالعداء لمجتمع البرمجيات الحرة والذي قد ينتج عنه خسارة أكبر. ينطبق هذا المبدأ أيضا على مجتمع المحترفين ففي مصر تمتلك مايكروسوفت العدد الأكبر من المطورين ومن المصلحة المتبادلة تحسين جودة هذا المجتمع وتشجيعه ليس فقط أن يكون مستهلك ومساهم فعال ف البرمجيات الحرة سواء داخل منظومة مايكروسوفت أو لينوكس أو غيرها.
وجهة نظري أن مايكروسوفت يمكن أن تصبح شريكا فاعلا ولكن ذلك يتطلب منها تغيير النظرة إلى مصر والمنطقة العربية عامة كسوق لتصريف المنتجات ولن يأتي هذا إلا بالضغط من مجتمع قوي يستطيع التفاوض والاستفادة من الظروف الجديدة التي نأمل أن تغيير من البيئة الاحتكارية التي كانت سائدة.
أود أن أنوه أني أرتبط بمصالح مباشرة مع شركة مايكروسوفت وقد ينتج عن هذا بعض التحيزات في أرائي إلا أني حاولت بقدر الإمكان التغلب على هذه التحيزات.

الأحد، 12 يونيو 2011

اختبار الوحدات Unit Testing

اختبار الوحدة هو مجموعة من التعليمات البرمجية التي تتأكد من صحة بعض الافتراضات المسبقة عن وحدة من التطبيق. الوحدة هنا هي أصغر جزء من التطبيق يمكن اختبارها وهي غالبا ما تكون method. على الرغم من وجود كلمة اختبار في العنوان فإن Unit Tests لا تهدف في الأساس إلى ضمان جودة التطبيقات أو استبدال مرحلة الاختبار للتطبيق ولكن العمل كمظلة أمان للحماية من مشاكل إجراء تعديلات خاصة في الهيكل الداخلي للتطبيق.

وازدادت أهمية Unit Testing كجزء أساسي من عملية التصميم الارتقائي Evolutionary Design حيث يقوم على البداية بأبسط الحلول للمشكلة الذي قد يكون ذو كفاءة أقل ثم تحسين التصميم تدريجيا عن طريق تقنيات Refactoring والتي تعتمد على تحسين الهيكل الداخلي لوظيفة معينة من دون تغيير النتائج. ولضمان عدم فشل الوظيفة أثناء التعديلات الهيكلية تكون اختبارات الوحدات هي المرجعية التي تسمح بالمغامرة تجربة أفكار عديدة دون العبث بالنتائج المنطقية للتطبيق.

لنأخذ مثالا لتطبيق بسيط للجمع بين رقمين حيث يدخل المستخدم رقمين وعند الضغط على زر يعرض ناتج الجمع

protected void btnAdd_Click(object sender, EventArgs e)

{

    double a, b;

 

    a = Convert.ToDouble(TextBox1.Text);

    b = Convert.ToDouble(TextBox2.Text);

    Label1.Text = Convert.ToString(a + b);

}

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

public class Calculator
{
    public double Add(string a, string b)
    {
        var ad = Convert.ToDouble(a);
        var bd = Convert.ToDouble(b);
 
        return Add(ad, bd);
    }
 
    public double Add(double a, double b)
    {
        return a + b;
    }
 }

وعندها يمكن كتابة الاختبار كالتالي

[TestFixture]
public class CalculatorTest
{
    [Test]
    public void AddOneAndOneShouldReturnTwo()
    {
        var calc = new Calculator();
 
        Assert.AreEqual(calc.Add("1", "1"), 2);
    }
}

هذا المثال يستخدم C# و NUnit ولكن الفكرة مشتركة بين المكتبات واللغات المختلفة ولكن الانطباع الأول قد يكون تم تحويل 5 أسطر من الكود إلى 20 فكيف الادعاء بأن Unit Testing تساعد في زيادة الإنتاجية. يعتمد هذا الافتراض على أن الوقت الأكبر في تطوير البرمجيات يكون في طباعة الأحرف بينما أي شخص قضى أكثر من عدة ساعات مطورا يعلم أن المشكلة تكمن في تقصي وتصحيح الأخطاء Debugging أو إدخال تعديلات وعندها تظهر فوائد الاختبارات الأوتوماتيكية. وكلما زاد تعقيد التطبيق والمزايا الملحقة به كلما زادت باضطراد فائدة الاختبارات. وحتى مع هذا الشكل من المنطق نستطيع ملاحظة فائدتان.

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

ثانيا فإن الاختبارات تقوم بمثابة توثيق ممتاز لا يكذب لمنطق التطبيق أفضل من كتابة فقرات شعرية في جمال وعبقرية تصميم تكتب قبل الشروع في العمل وتتحول لحبر على ورق مع التقدم في مراحل التطوير. لكن في حالة Unit Test فإنه عند تشغيلها فإنه تنطق بالحقيقة عند تشغيلها والتأكد من مجاراتها لواقع التطبيق. فعند انضمامي لفريق يعمل على تطبيق في منتصف مراحل التطوير أو عند تحميل مشروع مفتوح المصدر فإن أول شيء أبحث عنه هو الاختبارات التي تعطي المعلومات الأجود عن كيفية عمل التطبيق وذلك طبعا بشرط جودة الاختبارات.

على الرغم من بساطة المثال الذي كتبناه ولكنه يمثل الهيكل العام لاختبارات الوحدات والتي تتكون عادة من ثلاث مراحل يشار لها باختصار AAA أو Arrange Act Assert

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

هناك مجموعة من القواعد العامة لكتابة اختبار وحدة جيد لتكوين مظلة الأمان المنشودة لتحقق الاختبارات غرضها.

§ تأكد Assert وحيد لكل اختبار لأنه إذا تعددت فقد يكون دليل على تعقيد الاختبار وأنه يختبر العديد من السيناريوهات في نفس الوقت. المشكلة في هذه الحالة أنه عند فشل الاختبار لا يوجد مؤشر على المسبب لفشل الاختبار.

§ الدقة ، فالاختبارات يفترض فيها أن تكون المرجعية فإذا كانت غير دقيقة فإنها تفقد معناها.

§ الوضوح في التسمية ، فكما أسلفنا فإن واحد من أهم مزايا الاختبارات هي القيام بتوثيق التطبيق. كما أن وضوح التسمية تساعد على التعرف على السيناريو المسبب لفشل الاختبار.

نظرا لأهمية اختبارات الوحدات في نظم تطوير التطبيقات الحديثة فإن Frameworks أصبحت تصمم لتسهيل الاختبار كما أصبح ذلك من معايير جودتها فعلى سبيل المثال ASP.NET WebForms يعتبر مشكلة عند الاختبار وخاصة عند الاعتماد على HTTPContext أو Session عامة حيث أنها Sealed Classes وغير معتمدة على Interfaces وذلك يصعب من عملية Mocking لفصل الاعتمادات الخارجية ، كما أنه لا يشجع على الفصل بين المنطق وواجهة التطبيق وذلك يمنع الاختبار كما رأينا في بداية المقال. ولذا فإن ASP.NET MVC راعى ذلك في تصميمه لتسهيل الاختبار والتشجيع على الفصل بين الواجهة والمنطق باستخدام MVC Pattern.

أهمية الاختبارات تتضاعف مع لغات البرمجة الديناميكية مثل Ruby أو Python حيث إنها تكون بمقام الCompiler في التأكد من صحة العمليات وبالتالي يمكن الجمع بين الإنتاجية العالية في Dynamic Languages وأمان Static Languages.

لبدء كتابة الاختبارات يمكنك البحث عن مكتبة ال Unit Testing المستخدمة في اللغة التي تستخدمها والمتاحة تقريبا لكل اللغات تحت مظلة xUnit Frameworks والتي تتبع مكتبة JUnit التي كتبها Kent Beck الأب الروحي لاختبارات الوحدات.

الاثنين، 6 يونيو 2011

مقدمة عن الأجايل Agile كأداة لتخطيط وتنفيذ برمجيات ناجحة

سمعت وشاركت في الحوار التالي كثيرا وربما يدور الآن في مكان ما في هذا العالم بين مجموعة من المطورين المتحمسين وهم يتداولون:

"هنعمل المشروع ده صح المره دي. هانلم اللي عايزه ال User بالظبط ومش هاتتغير في النص ، ونعمل design document ما تخرش المية وهانسلم في الميعاد".

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

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

مشكلة أخرى تنتج عن هذا الأسلوب في التخطيط أن المصمم تكون مهمته هي وضع هيكل يناسب أي متطلبات مستقبلية ورغبة في اتباع الطرق المثلى (Best Practices) وفي غياب أي محددات فينطلق العنان للخيال ويتم وضع هيكل للتطبيق ولا هيكل سليمان وكثير من الكلمات الرنانة التي تنتهي بمقطع ity مثل Scalability, Customizability, Maintainability والنتيجة غالبا تصميم معقد يسقط مع بداية الضغوط لزيادة الإنتاجية واقتراب مواعيد التسليم فيبدأ التجاهل التدريجي لقواعد التصميم حتى يصبح في النهاية حبرا على ورق.

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

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

التخطيط

ما بين أسلوب اللاخطة الذي تتبناه فرق التطوير المبتدئة وأسلوب التخطيط الصناعي الذي تتبناه الشركات للسيطرة والتحكم في تكلفة ووقت التنفيذ والذي شهدت فشله في إنتاج تطبيقات تلبي حاجات المستخدمين فإن أسلوب الأجايل يتبنى نظرية التخطيط المستمر وينطلق أساسا من أن عملية التطوير تقوم على ابتكار حلول في خيال المستخدم ومحاولات استخراج تصورات دقيقة عن طريق حوارات ما بين محلل النظم والمستخدم غالبا ما تفشل في تكوين تصور دقيق لاحتياجاته. عوضا عن ذلك يتم تبني عدم التأكد في عملية التخطيط وهنا يأتي الخيط الرفيع بين ما بين التخطيط في فلسفة الأجايل والفوضى. فبدلا من أن يكون التخطيط مرحلة مستقلة تفترض أن نتائجها دقيقة فإن التخطيط يكون مستمرا ففي طريقة مثل سكرم Scrum يكون التخطيط بتقسيم مراحل التطوير إلى إصدارات Releases التي تمتد إلى بضعة أشهر والتي تقسم بدورها إلى مجموعة من الانطلاقات Sprints القصيرة والتي تدوم لأسبوع أو أسبوعين بحيث أن يكون فيها مجموعة من الميزات التي يتم إنجازها بشكل كامل وتكون قابلة للاختبار بواسطة المستخدمين. ويتم مراجعة الخطة بشكل يومي في اجتماع بين فريق العمل لمراجعة ما تم انجازه في اليوم السابق وما يخطط انجازه في اليوم الحالي وإذا ما كانت هناك معوقات تمنع أفراد الفريق من الإنتاج. في هذه الطريقة يتم مراجعة الخطة بشكل مستمر على المدى المتوسط عند التخطيط للإصدارات وعلى المدى القصير عند التخطيط للانطلاقات وصولا إلى التخطيط اليومي ولكن بتقييد دخول أي متطلبات جديدة أو تغييرات داخل الانطلاقة للحفاظ على تركيز الفريق.

هناك أساليب أخرى للتخطيط تحت مظلة الأجايل مثل Kan-Ban والتي تتبنى عملية مستمرة التدفق مخالفة لأسلوب الدورات المغلقة في Scrum تستمد هذه الطريقة مبادئها من نظريات Lean في التصنيع والتي تعتمد على تقليل الإهدار والفاقد في الموارد وفي هذه العملية يتم تقسيم التطبيق إلى مجموعة من الميزات Features والتي يتم ترتيب أولوياتها ثم تعريف مجموعة منها كوحدة أقل قابلة للتسويق Minimum Marketable Features وتباعا يبدأ فريق التطوير العمل في البناء ولكن مع تحديد حد أقصى للمهمات المتوازية لتقليل الفاقد الناتج عن النقل ما بين المهمات والحفاظ على تركيز الفريق.

كما أن هناك طرق أخرى مثل Crystal والتي تركز على متطلبات فرق العمل الصغيرة والمشاريع القصيرة و XP التي تعرف مجموعة أكبر من الممارسات التقنية في التنفيذ وكانت في وقت من الأوقات مرادفا للأجايل.

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

التصميم

قضيت جزءا معتبرا من حيات العملية في دور المعماري وبشكل أدق no-coding Architect أعمل على برامج الورد والفيزيو وبرامج تصميم UML لوضع تصورات لما يجب أن يتبعه المطورون في كتابة التطبيقات ومانت هذه الفترة بلا منافس الفترة الأقل إنتاجية في حياتي وأزعم أنها كانت كذلك ليس لأني معماري فاشل ولكن لأن أفضل المعماريات لاتوضع ولكن تنمو من خلال من خلال التصميم المستمر الذي يستجيب لمتطلبات المستخدمين فعند وضع المعمارية Architecture للتطبيق في المراحل الأولى للتطوير حيث هناك حالة من الضبابية يحاول المصمم توقع العديد من السيناريوهات المحتملة بلا أساس واقعي للأولويات. ولكن مع التقدم في مراحل التطوير تبدأ المتطلبات الحقيقية في الوضوح والتي إما أن تكون مختلفة عن تصورات المصمم أو يكون التصميم معقد بدرجة تعوق الإنتاج فيبدأ التجاهل التدريجي له حتى النسيان التام بلا مردود واضح للتصميم على جودة أو كفاءة العمل.

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

ترتبط البساطة بمبدأ مهم عند التصميم هو YAGNI أو You Ain't Gonna Need It وهو أحد المبادئ الرئيسية لمنظومة XP او eXtreme Programming وهو مبدأ يقضي بأنه لا يجب بناء شيء على افتراض الحاجة المستقبلية له فإنه في الغالب لن تحتاجه أو ستحتاج شيء مغاير. لذلك فإن القرارات المعمارية يتم تأجيلها حتى الحظة المسؤولة الأخيرة Last Responsible Moment ولا بد من التفريق هنا بين اللحظة المسؤولة الأخيرة والوقت الضائع فالفارق يتمثل أن في الأولى يتم تأجيل القرار حتى وضوح العوامل المؤثرة فيه والتأكد من الاحتياج لهذا القرار مما يؤدي إلى زيادة احتماليات جودة القرار ودقته بينما الثانية مجرد إهمال.

التنفيذ

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

دفعت هذه الاحتياجات لابتكار عدد من الحلول التي تساعد الفرق في الاستجابة السريعة ومن أهمها عمليات الميكنة في الاختبارات Test Automation على عدة مستويات.

اختبار الوحدات Unit Testing:

والتي تهتم باختبار الوحدات الأصغر من البرنامج وهي غالبا method وحتى تكون فعالة فإنه يتم تشغيلها باستمرار من قبل المبرمج مع كل تغيير يقوم به ولذا فلا بد من أن تكون سريعة التنفيذ. وحتى تكون نتائجها دقيقة يجب فصل الوحدة عن المؤثرات الخارجية مثل قواعد البيانات لذا تأتي تقنية Mocking كجزء أساسي من التقنيات المساعدة وهي تعنى بتكوين Fake Objects تحاكي الاعتمادات الخارجية External Dependencies وتفصله عن الجزء الواقع تحت الاختبار مما يضمن أنه إذا فشل الاختبار فإنه ناتج عن مشكلة في هذه الوحدة ومما أيضا يسرع في عملية تنفيذ الاختبارات بإزالة التفاعل مع الموارد البطيئة مثل قواعد البيانات والاتصال عبر الشبكات.

اختبارات التكامل Integration Testing:

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

التكامل المستمر Continuous Integration:

عادة ما يتكون فريق العمل من مجموعة من المطورين يعملون بشكل متوازي لتنفيذ مهمات معينة يتم التكامل بينها لتكوين المنتج النهائي وهذا يشكل تحدي كبير حيث أنه كما أسلفنا فإن عملية التطوير تعتمد على الابتكار وحل مشكلات صعب التنبؤ بها مسبقا لذا فإن الاتفاق المسبق على شكل التكامل يمثل تحديا مما يؤدي إلى أن تكون عملية التكامل مستهلكة للوقت ويتجنب المطورين تنفيذها بشكل مستمر مما يفاقم المشكلة حيث تتراكم التغيرات وبالتالي صعوبة الربط بينها. تأتي تقنية التكامل المستمر كحل لهذه المشكلة لحث المطورين على الدمج المستمر لأي تغييرات يقومون بها وميكنة التأكد من نجاح التكامل عن طريق Build Scripts تنفذ في أوقات مختلفة فعادة يكون هناك Script يعمل مع كل تعديل يتم دفعه Check-in إلى مخزن المصدر الخاص بالفريق Source Control Repository وبالتالي لا بد أن يكون سريعا فعادة مايتأكد من صحة عملية الترجمة Compilation ونجاح اختبارات الوحدات وإذا فشلت عملية البناء يخطر فريق العمل حتى يتم إصلاح المشكلة والمحافظة على المصدر المشترك سليما باستمرار. وهناك عملية بناء ليلية Nightly Builds تنفذ يوميا ويزيد فيها عادة تشغيل اختبارات التكامل وتجهيز نسخة لفريق مراقبة الجودة للتأكد من صحة ما تم تطويره وأحيانا كتابة اختبارات تكامل جديدة.

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