الأربعاء، 29 أغسطس 2012

المقدمة المُختصرة للبرمجة الكائنية oop كملف pdf

قمتُ بفضل الله تعالي بتحويل مقال المقدمة المُختصرة للبرمجة الكائنية oop إلي ملف pdf و رفعتُه علي حسابي علي موقع 4shared لإتاحة تحميله و تداوله و قراءته لمن يرغب في ذلك.

يمكنكم تحميل الملف من هــــنــــا.

تعقيبٌ علي مقال: بين الـawt و الـswing

تعقيبٌ علي مقال: بين الـawt و الـswing

عَلَّق أخٌ فاضلٌ علي مقالي بين الـawt و الـswing علي موقع وادي التقنية بقوله (بِتَصَرُّف):
ياه، أنت ما زلت تستخدم awt ! ظننتُ لا أحد يستخدمها الآن، ما رأيك في أن تستخدم مكتبة SWT؛ على الأقل هي أسرع من swing ومظهرها أفضل بدرجات، وهي في تطور مستمر.
بالمناسبة: هل السرعة مطلوبةٌ في التطبيق الذي تُطوره؛ لأنه من المعروف أن جافا في تطبيقات سطح المكتب بطيئةٌ بشكلٍ عام ؟ وكذلك من المعروف أن قوة جافا تظهر في المُخَدِّمات و الأجهزة المحمولة.
فقلتُ:

أنا لم أتعمق من قبل في دراسة الجافا و العمل الاحترافي بها، و كنتُ أستخدمُ الـ#C و الـ.NET في كل شيءٍ يخصني. و لذلك نسيتُ مسألة قِدَم الـawt و المشاكل التي تظهر حين استخدامها، و تذكرتُ هذا بعد ما حدث :)
بالنسة لسرعة التطبيق فلم تتأثر ببطء الواجهة الرسومية بشكلٍ كبير؛ لأنها لا تستخدمها إلا في الدخل و الخرج، و يمكن للبرنامج أن يستخدم سطر الأوامر العادي لأداء هذه المهمة إذا رغب مُستخدمه في ذلك، و مُحاكي سطر الأوامر الخاص له بعض الحالات الخاصة التي تجعله الأفضل (كما أنني بصراحة كنتُ أريد تعلم كيفية صنع مُحاكيات سطر الاوامر فقلتُ: وافق شِنٌ طبقه ^_^)

الثلاثاء، 28 أغسطس 2012

البرمجة الكائنية بدون وراثةٍ متعددة

البرمجة الكائنية oop بدون وراثةٍ متعددة multiple inheritance تماماً كزوجةٍ مُتدينةٍ جميلةٍ و لكنها لا تُنجب؛ بالتأكيد وجودها أفضل بكثيرٍ جداً من عدم وجودها، و لكن لا يُمكنك أن تُنكر أنه لا أحد يرغب في البقاء بلا أبناء.

السبت، 25 أغسطس 2012

مقدمة عن البرمجة الكائنية object oriented programming OOP


مقدمةٌ عن البرمجة الكائنية
 object oriented programming 
OOP


الشرح التالي هو تعديلٌ غير كبير لشرحٍ كنتُ قد كتبتُه لمجموعةٍ من زملائي في الكلية (في السنة قبل الأخيرة لنا فيها)، أشرح فيه نمط البرمجة المسمي بالبرمجة المَقُودة بالكائنات object oriented programming أو اختصاراً (البرمجة الكائنية). و قد وجدتُه بعد كل تلك الفترة التي نسيتُه فيها بسيطاً و ربما جيداً، فقلتُ أضعُه للناس ليستفيدوا منه. و ربما أقوم في المستقبل بإذن الله تعالي بتكملته و/أو التعديل فيه.

ماهية البرمجة الكائنية:

لكي نفهم ماهية و خصائص نمط البرمجة الكائنية oop paradigm يجب علينا أن نتفهم المثال التالي:
فلنفترض أننا نريد كتابة برنامجٍ يقوم بإنشاء خَمس حساباتٍ لخمسة أشخاصٍ في خمسة شركاتٍ مختلفة، و يقوم بحساب مستحقاتهم المالية لدي الشركة بعد مرور ثلاث سنوات بمعرفة نسبة الربح السنوي المعتادة من رأس المال. مع ملاحظة أن الكود سيكون بنمط البرمجة العادي (أي بدون استخدام الأصناف classes و الكائنات objects).

double account1 = 100, profit1 = 0.1;
double account2 = 150, profit2 = 0.15;
double account3 = 200, profit3 = 0.20;
double account4 = 175, profit4 = 0.25;
double account5 = 200, profit5 = 0.30;


double after_years(double old_account, double profit, int years){
for(int i = 1; i <= years; i++){
old_account = old_account * profit + old_account;
}
return old_account;
}

void main(){
account1 = after_years(account1, profit1, 3);
account2 = after_years(account2, profit2, 3);
account3 = after_years(account3, profit3, 3);
account4 = after_years(account4, profit4, 3);
account5 = after_years(account5, profit5, 3);
}


بملاحظة البرنامج السابق سوف نري أننا لتمثيل كل حسابٍ من الحسابات  المالية استخدمنا متغيرين من نوع double: 
  • الأول لتمثيل النقود التي يحتويها الحساب  account
  • الثاني لتمثيل نسبة الربح profit
و تم  تكرار هذا مع كل حسابٍ من الحسابات المالية، بالطبع مع تغيير أسماء المتغيرات للتمييز بينها.
إذاً فالسؤال المنطقي الآن: هل يمكنني كمبرمجٍ أن أختصر كل ذلك الكود ما دام الكثير منه مكرراً بالفعل ؟

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

و بالتطبيق علي المثال السابق نري أن التقسيم الأَوَّلي لما سنحصل عليه سيكون كالتالي:
double account, profit;
double after_years(double old_account, double profit, int years){
for(int i = 1; i <= years; i++){
old_account = old_account * profit + old_account;
}
return old_account;
}

يمكن أن نُطلق علي الكود السابق إسم caccount اختصاراً لـcompany account و هو اسمٌ معبرٌ جداً عن وظيفته.
و في البرنامج الأساسي سنكتفي بطلب نسخ الكود caccount خمس مرات من مترجم اللغة بأسماء account1  account2   account3   account4   account5.
caccount account1;
caccount account2;
caccount account3;
caccount account4;
caccount account5;

فماذا سيفعل الحاسوب بعد حجز أماكن لتلك الكائنات في الذاكرة ؟
سوف يقوم بعمل ما يلي تقريباً:



و بداخل كل وحدةٍ من الوحدات المحجوزة تُوجد المتغيرات الموجودة في الكود المُكرر الذي كتبناه من قبل و وضعناه جانباً.
فلو كتبنا في البرنامج:
 account1.account
فإننا نعني المتغير account الذي هو من نوع double و المحجوز للنسخة المُسماة account1.
و هكذا مع:
account2.account

و غيرها.

و لو أردنا أن ننفذ دالة علي النسخة account1 بحيث تعملُ باستخدام متغيراتها الخاصة فإننا نكتب الكود التالي:
account1.methodname();

مثال:
account1.newaccount();


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

لا.
فماذا لو أنني أردتُ إعطاء قيم ابتدائية للمتغيرات الموجودة داخل النسخ الجديدة في نفس سطر تعريف كل نسخةٍ منها، كيف يمكنني فعل هذا ؟
و ماذا لو أنني أردتُ منع الوصول المباشر للمتغيرات داخل النسخ، مثل الأمر:
account1.account = 1000;

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

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



التوصيف المُصطلح العلمي العربي المُصطلح العلمي الإنقليزي
كود مكرر صِنْف class
نُسخة نسخة، كائن Object, instance
متغير داخل صنف حقل بيانات Data field
دالة داخل صنف دالة حالة Instance method

و لنجب الآن عن الأسئلة التي سبق و طرحناها.
أما كيفية إعطاء حقول البيانات قيماً ابتدائية في نفس جملة التعريف فيتم عن طريق ما يُسمي بالمُشَيِّد constructor، و هو دالةٌ لها نفس اسم الصنف class بدون أي نوعٍ من المُخرجات (ليس حتي void).
و ينقسم المُشَيِّد إلي نوعين:
  • المُشَيِّد الافتراضي default constructor
  • المُشَيِّد ذو المُدخَلات parameterized constructor

و هذا هو المثال السابق بالكامل (مع إضافة مُشَيِّداتٍ من ذوات المُدخَلات):
public class caccount {
double account, profit;

public caccount(double account, double profit){
this.account = account;
this.profit = profit;
}
public static void main(String[] args){
caccount account1 = new caccount(100, 0.1);
caccount account2 = new caccount(150, 0.15);
caccount account3 = new caccount(175, 0.20);
caccount account4 = new caccount(200, 0.25);
caccount account5 = new caccount(250, 0.3);
}

double after_years(double old_account, double profit, int years){
for(int i = 1; i <= years; i++){
old_account = old_account * profit + old_account;
}
return old_account;
}
}

و يقوم البرنامج بحجز مكانٍ في الذاكرة للكائن الجديد ثم تنفيذ المُشَيِّد الافتراضي لو كتبنا ما يلي:

caccount  account1 = new  caccount();

و لاحظ عدم وجود قيم بين قوسي المُشَيِّد المُستدعَي.
بينما يقوم البرنامج بحجز مكان الذاكرة ثم تنفيذ المُشَيِّد ذي المُدخلات لو كتبنا ما يلي:
caccount  account1 = new  caccount(100, 1.0);

و لاحظ وجود قيمٍ بين قوسي المُشَيِّد المُستدعَي. و في هذه الحالة يكون:
account2.account = 100
account2.profit = 0.1

أما منع الوصول المٌباشر لحقول البيانات فيكون ببساطة بإعطائها الخاصية private عند تعريفها، مثل:
private double account;

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

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

أين تتم كتابة الأكواد:

في هذه المرحلة نكون قد وصلنا إلي تصورٍ جيدٍ لمفهوم البرمجة الكائنية oop و كيفية الاستفادة منها في تصغير حجم البرنامج و حماية حقول البيانات من تدخل المستخدم النهائي، و لكننا حتي الآن لا ندري أين تتم كتابة كود الصنف الفرعي و أين سنكتب الكود الذي سيستخدم هذا الصنف ؟
و هذه نقطةٌ هامةٌ للغاية تختلف فيها لغات البرمجة؛ ففي لغة الـ++C مثلاً سوف نجد أننا سوف نستخدم ملفات الـheader files (أو ملفات التَرْويسَة ) لكي نكتب فيها كود الـصنف و يكون لها الامتداد (h.)، و سيكون علينا أن نكتب الكود بنفس طريقة الـ++C التي تشترط كتابة مُلخص الصنف specification ثم بعد ذلك يأتي كوده التفصيلي (أو ما يُسمي بالبناء implementation).
و كذلك فإنه يمكننا أن نكتب التلخيص في ملف ترويسة و البناء داخل ملف آخر له الامتداد cpp. مع كتابة الجملة التالية في بداية هذا الملف الجديد:
#include "caccount.h";

لجعل المُترجم يفهم أن الملفين مرتبطان ببعضهما البعض.
هذا بالنسبة للـ++C، أما في حالة الـjava فيمكننا كتابة كود الصنف في نفس ملف البرنامج الأصلي، أو في ملفٍ مستقل لكن بحيث:
  • يشتمل كل ملفٍ مستقلٍ علي صنفٍ واحدٍ فقط يماثله في الاسم، و بإمكاننا كتابة أصنافٍ أخري داخل ذلك الصنف الواحد.
  • يكون امتداد الملف المستقل(java.)

مفهوم الوراثة inheritance و علاقته بمبدأ إعادة الاستخدام:

بعد الانتهاء من كتابة برنامجٍ ضخم بنمط البرمجة الكائنية سوف نجد أنه قد تم كتابة عددٍ كبيرٍ من الأصناف المُستقلة التي سهلت علينا العمل و أسرعته بمعدلاتٍ فائقة.
لكن السؤال الحيوي هنا: هل يمكنني الاستفادة منها بصورةٍ أكبر ؟

بالطبع نعم؛ حيث يمكنني إعادة استخدام reuse هذه التصنيفات الموجودة عندي في كتابة برامجي الجديدة دون الحاجة إلي إعادة كتابة كودها مرةً أخري أي أنني أصنع مكتبتي الخاصة بي، تماماً كالمكتبات القياسية للغات البرمجة، حيث أن الأصناف التي نستخدمها في برامجنا التي نكتبها بتلك اللغات ليست إلا أكواداً قام بكتابتها متخصصون في شركة البرمجيات و أراحونا من عناء كتابتها منذ البداية.
و علي سبيل المثال لو أنني احتجتُ للصنف caccount أثناء كتابتي لبرنامجٍ جديدٍ بلغة الـ++C فسوف أقوم فقط بضمه للبرنامج بالعبارة:
#include "caccount.h";

 و بذلك يمكنني استخدامه بمنتهي الحرية.

لكن ماذا لو أردتُ استعمال هذا الصنف مع إحداث بعض التغييرات فيه (كتابة حقول بياناتٍ إضافية، أو كتابة دوالٍ إضافية، أو حتي تعديل أكواد دوالٍ موجودةٍ من قبل) مع الاحتفاظ بهيكل و مكونات الصنف الأساسي كما هي، فما العمل ؟
 الحل هنا يكمنُ في مفهوم الوراثة؛ فحينما أُخبر اللغة أنني أريد كتابة تصنيفٍ جديدٍ فلنفترض أنه new_caccount يرث الصنف caccount فإنه يكون مفهوماً لديها أن الصنف الجديد يحتوي علي كل حقول البيانات و الدوال التي يحتويها الصنف القديم مع وجود إمكانية التعديل كما سبق و شرحنا.
و تختلف اللغات فيما بينها في مدي و كيفية الوراثة: أهي وراثة متعددة multiple inheritance بما يعني أن الصنف الواحد يمكنه وراثة عددٍ غير محدودٍ من التصنيفات الأخري كما في الـ++C و الـeiffel، أم هي وراثة أُحادية أي أن الصنف لا يمكنه وراثة أكثر من صنفٍ واحدٍ فقط كما في لغات الـjava و الـ#C. و ربما نتحدث عن هذا بالتفصيل في شروحاتٍ قادمةٍ بإذن الله تعالي.

إلي هنا نكون قد أنهينا المفاهيم الأساسية في عالم البرمجة الكائنية، و لكن أشياء كثيرة للغاية ما زالت تنتظر و لكنها تتأثر بماهية اللغة التي سنبرمج بها، لذلك ستكون هذه الأشياء في الـ++C مختلفة الشكل و الخصائص عنها في الـjava و عنهما في الـ#C.
و منها:
  • الواجهات interfaces
  • الهياكل structs
  • التعدادات enumerations
  • الوسائط delegates
  • الاحداث و تعهد الأحداث events and events handling
و غيرهن.

الجمعة، 24 أغسطس 2012

بين الـawt و الـswing

بين الـawt و الـswing

كنتُ قد قلتُ من قبل أن هناك تنبيهاتٍ لأخطاء زمن تنفيذ runtime errors تظهر أثناء تجربة برنامجي الذي أعمل عليه حالياً في بيئة الـJVM، و ذلك بشكلٍ لا يمكن توقعه ! و قد ظننتُ ساعتها أن هذا ناتجٌ عن مشاكل في نظام التشغيل عندي (كتخمينٍ مبدئي) و قد تبين لي الآن  خطأ هذا الظن.
و كذا فقد كانت هناك مشاكل تواجهني بخصوص اللغة العربية في واجهة المشروع، حيث أن في البرنامج توجد تلك النافذة frame التي يوجد بها صندوق نصوص textarea يقوم بالتفاعل مع المستخدم بعرض نتائج له و أخذ مُدخلاتٍ عند اللزوم بما يُماثل محاكيات سطر الأوامر   command line emulators، و قابلتني مشكلة اتجاه النص في صندوق النصوص لأن الاتجاه الافتراضي كان من اليسار لليمين، و كان من اللازم تغيير ذلك بتغيير إعدادت صندوق النصوص.

و هنا ظهرت المشاكل الغريبة: فقد جربتُ حلين هما استخدام:



private Locale arabic = new Locale("ar", "KW");
private ComponentOrientation arabicOrientation =
ComponentOrientation.getOrientation(arabic);
console_area.setComponentOrientation(arabicOrientation);
ثم بعد ذلك استخدام:



console_area.applyComponentOrientation(arabicOrientation);

و لكنهما لم يعملا مطلقاً !
و حينما بحثتُ علي الشبكة عن مثيلٍ لهذه المشاكل الغريبة وجدتُ أن أحدهم قام بالإبلاغ عن هذه المشكلة علي موقع sun، و كان الرد عليه أنها مشاكل تتعلق بمكتبة awt التي "لا تعمل" فيها دالة applyComponentOrientation  أصلاً  لعدم وجود كودٍ لها في الصنف textarea !
يعني أن الدالة مجرد حبرٍ علي ورق !
بل الأنكي أن الرد أكمل أنه ليست هناك نية لإصلاح هذا الأمر الآن ! 
و قد نصح صاحبُ الرد السائلَ أن يستخدم مكتبة swing بدلاً من الـawt في عمله.
و كالعادة لم "أكذب خبراً" و انطلقتُ لأجرب هذا الحل الجديد، فقمتُ بعمل نسخةٍ احتياطيةٍ من عملي الأخير حتي لا أُجازف به عند عمل التغييرات الجديدة التي ربما تكون جذرية. 
ثم قمتُ بحذف صندوق نصوص مكتبة awt و أدرجتُ صندوق نصوص swing، و الجيد هنا أن مكونات الواجهة API التي استعملتُها مع صندوق نصوص awt كانت موجودةً بأكملها في صندوق نصوص swing (و لا أدري هل الواجهتان متماثلتان بالكامل أم لا) و بالتالي لم أحتج لتغيير أي شيءٍ في الأكواد نهائياً (بعد جعل اسم الصندوق الجديد مماثلاً لاسم الصندوق المحذوف بالطبع).

و حينما اختبرتُ البرنامج وجدته قد تلافي مشكلة اتجاه النصوص بنجاحٍ و الحمد لله تعالي، و الرائع أن تلك الاستثناءات التي تحدثتُ عنها من قبل أصبحت أقل بكثيرٍ جداً عما كانت عليه قبلاً، بما يعني أن السبب الرئيس وراء ظهورها هو استخدام الـawt، أو علي الأقل استخدامها مع الـswing في نفس المشروع (و إن كنتُ أُرَجِّح الظن الأول)، و حينما قللتُ الاعتماد علي الـawt قلت المشاكل بالتوافق.

بعد ذلك واجهتني مشكلةٌ أخري هي أنه: عند كتابة نصٍ كبير الحجم في صندوق النصوص الجديد لا يتم عرض آخر الأسطر التي تم كتابتها، بل تظل الأسطر الأولي هي التي في المقدمة، و لرؤية الأسطر الأخيرة يحتاج المستخدم لاستخدام عمود الإزاحة scrollbar يدوياً و هو أمرٌ غير عملي لمثل هذه البرامج، فاحتجتُ إلي كودٍ لجعل الانزلاق يتم تلقائياً و وجدتُه بالفعل بحمد الله تعالي، و بعد تعديلٍ بسيط أصبح كما يلي:




int pos = console.console_area.getText().length();
console.console_area.setCaretPosition(pos);
و بالفعل عمل مُحاكي سطر الأوامر بشكلٍ جيد، و إن كان أثقل في العمل من النسخة التي كانت تعمل بالـawt بشكلٍ طفيف.

الخلاصة هنا أن استخدام الـswing أفضل و أكثر أمناً من الـawt التي يتم إهمالها تدريجياً بما يُوحي بالرغبة مستقبلاً في إسقاطها من الحسابات تماماً.

الخميس، 16 أغسطس 2012

تراكم موارد التنقيح

تراكم موارد التنقيح


أعني هنا بـ"موارد التنقيح": "كل ما يستخدمه المبرمج أثناء عملية التنقيح debugging باستثناء برنامج المُنقِّح debugger نفسه، مثل الملفات النصية أو الصور أو غيرها من الأشياء التي يعمل عليها البرنامج محل الاختبار".

و تفصيل هذا أنه حينما تُضيف خاصيةً جديدةً إلي برنامجك فمن المُستحسن أن تقوم باختبارها علي الفور لتري هل تعمل كما تحب أم لا، و بعد الانتهاء من هذا الاختبار فمن الخطأ أن تلقي بالأدوات التي صنعتَها لإجراء هذا الاختبار، يعني مثلاً لو أنك تختبر مترجماً compiler للغةٍ افتراضيةٍ ثم قمت باختبار خاصيةٍ جديدةٍ في اللغة عن طريق ملف كود مكتوبٍ بها، فمن الخطأ بعد إجراء تلك التجربة أن تلقي هذا الملف و ألا تحتفظ به لما بعد.
سبب هذا أنك فيما بعد سوف تحتاج إلي إجراء اختبار أسميه اختبار التوافقٍ العكسي backward compatibility test لتري هل التغييرات الجديدة التي صنعتَها في كود البرنامج قد تسببت في مشاكل مع الأكواد القديمة بما يؤدي إلي عدم عمل الخصائص القديمة التي أضفتَها للبرنامج بشكلٍ صحيح. و لو أنك احتفظتَ بملفات الاختبارات التي تُجريها لتستخدمها في كل مرةٍ تريد فيها الاطمئنان علي التوافقية العكسية فسيوفر هذا عليك كثيراً من وجع الرأس.

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

الأحد، 12 أغسطس 2012

خدمة تدوينٍ للفيسبوك

خدمة تدوينٍ للفيسبوك

الشعبية الجارفة التي حظي بها الفيسبوك facebook في الأعوام الأخيرة جعلته ركناً هاماً للغاية لمن يهتم بالتواصل مع الآخرين و إيصال آرائه إليهم، و منذ فترةٍ غير بعيدةٍ كان التدوين (و لا يزال عند الكثيرين) يقوم بذات الدور و إن كان علي نحوٍ أقل قوة.
و لا يستطيع أحدٌ أن ينكر أن الفيسبوك بالفعل شبكةً هائلة الانتشار و تكفل الانتشار غير المسبوق لمن يستطيع تسويق نفسه فيها، أما التدوين فهو أمرٌ نخبويٌ أكثر من الفيسبوك؛ فغالباً ما يرتبط التدوين في أذهان الناس بالأدباء و الشعراء الذين يقولون كلاماً غير مفهوم. 

لكن مشكلة الفيسبوك الأساسية أنه لا يوفر أي آليةٍ لأرشفة ما يتم نشره فيه، و تضيع الكتابات الهامة فيه وسط زحامٍ هائلٍ من المنشورات غير المهمة و يصير الوصول إليها بعد فترةٍ بسيطةٍ شيئاً أقرب إلي الخيال العلمي.
كما أنه لا يمنح الكاتب أي فرصةٍ لتنسيق مقالاته أو جعلها أكثر جمالاً شكلياً، فحتي (الملاحظات notes) التي تتيح كتابة مواضيع طويلة علي الفيسبوك لا تسمح بتنسيقات احترافية علي المقالات، كما أنها لا تسمح بوضع الصور بأوضاعٍ ملائمةٍ تجعل الموضوع أكثر راحةً بصرية.
لذا فنري أن المدونين يتعاملون مع الفيسبوك علي أنه شبكةٌ دعائيةٌ لمقالاتهم التي يكتبونها علي مدوناتهم ليس إلا، و يحاولون جذب القراء لهم من خلال ذلك الوسط الغاية في النشاط من خلال مشاركة روابط تلك المقالات علي صفحات و مجموعات الفيسبوك.


لذا فبعد تلك المقدمة البسيطة إليكم الفكرة التالية:
إنشاء تطبيق علي الفيسبوك يسمح لمستخدمه بإنشاء مدونةٍ احترافيةٍ مرتبطةٍ بحسابه الشخصي علي ذلك الأخير، و سيكون لهذا التطبيق بطبيعة الحال القدرة علي الاستفادة من إمكانات الفيسبوك الكاملة مثل:
  • وجود أصدقاء friends لإقتراح متابعة المدونة عليهم، و إرسال إشعارات notifications لتنبيههم إلي الجديد الذي يُنشر في المدونات التي يتابعها كلٌّ منهم.
  • النشر في المجموعات التي يشترك فيها صاحب المدونة بسرعة و بساطة.
  • كما أن الفيسبوك سيستفيد من ذلك التطبيق بأن يربط أعضاءه به أكثر و أكثر، و يقدم لهواة المقالات الاحترافية مثلي حلاً مدمجاً لا يخرجون به عن حيزه، مما يضمن له رسوخاً أكبر و أكبر.

الخميس، 9 أغسطس 2012

كيفية المساعدة من الآن حتي البدء في العمل في الموسوعة رسمياً ؟

كيفية المساعدة من الآن
حتي البدء في العمل في الموسوعة رسمياً ؟


هناك سؤالٌ و اقتراح من الأخ Al Anazi Salem استأذنته في نشرهما هنا بتصرفٍ بسيطٍ فأذن لي:

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

إذا أردت أن تساعد حالياً فبإمكانك أن تقوم باختيار لغةٍ أخري غير اللغات التي قمتُ بتلخيصها و تتعلمها، و في أثناء تعلمك لها قم بتلخيصها بشكلٍ جيدٍ و واضح، و حينما يتم الإعلان عن المشروع رسمياً (علي الأكثر سننتظر لمدة 4 أشهر) سوف نطلب من الآخرين تقديم ما يرغبون في تقديمه من تلخيصاتٍ للغاتٍ لا نمتلك مادةً علميةً عنها.
هذا بالطبع إذا لم يكن الأمر ثقيلاً عليك أو شاغلاً لك عن بقية أمورك الحيوية.  
بالنسبة للغات التي يمكنك تلخيصها فأنا أرشح لك:
  • php
  • perl
  • eiffel
  • lisp
  • #F

بالنسبة لاقتراحك بإضافة قسم لقواعد البيانات فمن الممكن عمل موسوعةٍ أخري مخصصةٍ للغات الاستعلام SQL المختلفة. لكنها ستكون موسوعة منفصلة عن موسوعة الألسن.

الثلاثاء، 7 أغسطس 2012

تعقيبٌ علي مقال (تلخيصٌ لفكرة موسوعة الألسن و محتوياتها)

تعقيبٌ علي مقال 
(تلخيصٌ لفكرة موسوعة الألسن و محتوياتها)

عقَّب أحد الفضلاء علي مقالي ( تلخيصٌ لفكرة موسوعة الألسن و محتوياتها) في وادي التقنية بقوله (بتَصَرُّفٍ):


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

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

لنقل أن فلان ليس لديه أي خبرةٍ برمجية، و هو يحب تعلم بايثون أو روبي.الخ. حسناً دخل للمستندات قرأ أن الدالة الفلانية كذا و أن الحلقة التكرارية كذا و... و ... بعد القراءة هذه كلها تَبَقَّى شيءٌ و هو: أن يفهم كيف يتم ربط الدالة الفلانية بالكود الفلاني و .. و.. و لتنفيذ المهمة الفلانية، ليس بالضرورة وضع أمثلةٍ لكل شيء لكن على قدر المستطاع هذا يسرع ويساعد بشكل كبير على الفهم والتأقلم مع اللغة.


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

فكان ردي ما يلي:

الأساس في الموسوعة أنها ستكون ذات إصداراتٍ رقميةٍ بإذن الله تعالي، و بالنسبة للكتاب الورقي فأنا أيضاً لا أحبه و أُفَضِّل أن تكون الأمور كلها إلكترونيةً صرفة بكل ما يعنيه هذا من سهولة التعديل و التحديث و النشر و الوصول. و لكن لو قَدَّر الله تعالي للمشروع أن يكبر و تصير الموسوعة واقعاً فربما يريد محبو الكتب الورقية الحصول علي أجزاء الموسوعة بشكلٍ ورقي (و أنا أثق أن هذا الموقف سيحدث).
بالنسبة لمحتويات الموسوعة فلا يمكن ضم الشرح الذي يحتاج إليه المبتدئون إليها؛ فأصلاً فكرة الموسوعة هو أن تكون "تلخيصاً" يحل محل الإسهاب الموجود في الشروحات المعتادة، و الشيء الوحيد الذي سيُسْتثنَي من هذه القاعدة هو: شرح القواعد الصعبة بإيجاز عند أول ذكرٍ لها. و علي المبتديء أن يستعين بالشروحات المتخصصة أولاً  ثم يلجأ للموسوعة لتذكر ما فهمه بالفعل من قبل.
أما الفرق بين الموسوعة و بين توثيقات لغات البرمجة المعتادة فهو الإيجاز في ذكر القواعد في الموسوعة، و كذا الأبواب الإضافية التي نتحدث فيها عن تاريخ اللغة و إصداراتها المختلفة و ربما أفضل بيئات التطوير المتكاملة IDE المتاحة لها (باختصارٍ بطبيعة الحال)، بالإضافة إلي توحيد الشكل بين تلخيصات اللغات المختلفة في الموسوعة، و الأهم أن كل هذا سيكون باللغة العربية و بأسلوب سلسٍ موحَّد.

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

الاثنين، 6 أغسطس 2012

مدونةٌ خاصةٌ لمشروع موسوعة الالسن

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

الأحد، 5 أغسطس 2012

خاطرةٌ عن الـ#C

خاطرةٌ عن الـ#C

لغة الـ#C لغةٌ رائعةٌ و فاتنة بالفعل، و قد بدأت مشواري البرمجي الحقيقي معها و مع بيئة الفيجوال ستوديو visual studio، لكن أكبر المشاكل التي تواجه الـ#C أن الجميع يعتبرها واجهةً فقط لتقنية الـ.Net (و قد كنتُ منهم لفترةٍ طويلة)، لذلك فإن كل من يبرمج بها يستخدمها و هو يؤمن أنه ما دام يستخدمها فلن يستطيع البرمجة إلا للويندوز فقط، بل و سيظل مرتبطاً أبد الدهر ببيئة الفيجوال ستوديو و مكتبة الـ.NET.


و من أسباب ذلك أنه علي الرغم من قوة الـ#C إلا أن نقلها إلي منصات متعددة من الصعب أن يكون كنقل الـjava مثلاً: فالجافا مصممة من الأساس لكي تتنقل برامجها بحرية عبر المنصات المختلفة، و هذا مراعي في مكتبتها القياسية الـJDK، بينما مكتبة الـ.Net بها أجزاء من الصعب جداً نقلها أو مُحاكاتها بالكامل (مثل جزء الواجهة الرسومية GUI الضخم) و بالتالي لا يكون أمام المبرمج الذي اعتمد علي أكواد مكتبة الـ.Net غير المتنقلة إلا أن يبقي علي منصة الويندوز فقط، و للأسف فمعظم مبرمجي الـ#C قاموا بالفعل بعمل الكثير من البرامج الضخمة منذ فترة بطريقةٍ شديدة الارتباط بنظام التشغيل ويندوز و صار من المستحيل عملياً تحويل هذه البرمجيات للعمل علي منصاتٍ أخري.

و مما يزيد الطين بلةً أن هناك براءات اختراع مملوكة لمايكروسوفت يتم استخدامها (بالطبع) داخل مشروع مونو mono (الذي يعتبر البديل مفتوح المصدر لمنتجات مايكروسوفت التي تربط الـ#C بها، و يعطيها القوة التي تضاهي قوة الجافا)، و بالتالي يضع هذا المبرمجين تحت طائلة مايكروسوفت التي لا تري إلا مصالحها (بطبيعة الحال).

السبت، 4 أغسطس 2012

كنتُ أظن حتي رأيت

كنتُ أظن أن الـ++C هي أصعب لغة برمجة حتي رأيتُ الـAda.
كنتُ أظن الـ#C هي أضخم لغة برمجة حتي رأيتُ الـVB.NET.
كنتُ أظن أن الـjava هي أكثر اللغات تزمتاً من حيث هيكل البرنامج حتي رأيتُ الـobject pascal.

اختبار المترجمات و المفسرات جـ1

اختبار المترجمات و المفسرات جـ1

من أصعب النقاط في برمجة المترجمات compilers و المفسرات interpreters أنها (علي خلاف معظم المجالات البرمجية الأخري) تنتمي لفئةٍ صغيرةٍ جداً من التطبيقات التي لا يُسمح أن يكون فيها أقل القليل من الأغلاط bugs أو المخالفة للمواصفات القياسية الخاصة بها، فالبرنامج النهائي يجب أن يكون في أعلي درجات الموثوقية و الاعتمادية و أن يفعل "كل" ما صُمم لفعله بالشكل "المُتوقع"، و إلا فسيُعد غير صالحٍ للاستعمال الطبعي !

لتقريب هذه الصورة إلي الذهن: يمكنك أن تتخيل أن تكتب برنامجاً بلغة الـjava ثم تقوم بترجمته، و عند تشغيله تفاجأ بأنه لا يعمل كما يُفترَض، فأين الغلطة إذاَ: هل هي في برنامجك المكتوب أم في مترجم الجافا ؟؛ فهذا الموقف سيصبح كارثةً متكررةً بشكلٍ لا يُطاق لو سُمح بأن يكون المترجم أو المفسر قابلاً لوجود الأغلاط المنطقية فيه بنفس كثافة البرمجيات الأخري.

إلا أن هذا لا يدفعنا إلي الظن بأن هذه البرامج "دائماً" ما تكون مثالية من هذه الناحية، بل هو ينبهنا فقط إلي أن مرحلتا الاختبار testing و التنقيح debugging لهذا النوع من البرامج لا تشبهان ذات المرحلتين في حالة البرمجيات الأخري التي تقبل التساهل فيها علي نحوٍ أكبر.
فيجب هنا أن نقوم باختباراتٍ أكبر كثافةً عددية، و أشد تغلغلاً في احتمالات الاستعمال usage cases المختلفة، بل يجب أن يخضع البرنامج للاستعمال القاسي أكثر من الحالة الطبعية، بما في ذلك أشد حالات الاستعمال شذوذاً و غرابةً و قلة حدوث؛ و ذلك حتي يتم التنبه إلي أي غلطةٍ منطقيةٍ قد تكون في مكانٍ صعب الوصول إليه في مجال الاحتمالات الإستخدامية المختلفة.

--------------------------
للمزيد من المعلومات:
http://en.wikipedia.org/wiki/Compiler_correctness