الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

هندسة البرمجيات

بدأه mohref في 24 أكتوبر 2005 · 19 رد · 3,534 مشاهدة · في هندسة البرمجيات
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

بسم الله الرحمن الرحيم

أريد أن أتكلم عن فكرة بسيطة لكن ذات فعالية كبيرة في مجال البرامج الضخمة باستخدام لغات البرمجة الشيئية أو غرضية التوجه إذا أحببتم تسميتها (Object Oriented)

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

إذا تتلخص عملية بناء البرنامج بالتالي:

1- جمع المتطلبات وهذه العملية هي أن نقوم بالذهاب إلى الشركة او المؤسسة التي نريد تطوير البرنامج لها ونبدء بالأسئلة عن طبيعة البرنامج والأقسام المدرجة به ومن الممكن أيضا ان نقوم بالدوام لفترة في هذه الشركة حتى نستطيع التعرف على طبيعة العمل الذي نريد أتمتته ومن ثم نجمع هذه المعلومات ضمن وثيقة تدعى وثيقة المتطلبات (Requirements Specification) والتي بصريح العبارة تتضمن كل (شاردة و واردة) في هذه الشركة

2- مرحلة التحليل وتتضمن تحليل هذه المعطيات و تنظيمها ويتخللها احيانا العودة إلى المرحلة السابقة للسؤال عن بعض المتطلبات

3- مرحلة التصميم ووتتضمن تحويل المعلومات التي حصلنا عليها في مرحلة التحليل عبر خطوات منظمة إلى ان ينتج معنا في النهاية صفوف ((Classes بجميع الطرق (Methods) الخاصة بهذه الصفوف وجميع المتحولات (Data Member) أيضاً

4- وفي النهاية تأتي مرحلة الشيفرة (Coding) والتي تتضمن تحويل الصفوف المرسومة في مرحلة التصميم الى صفوف مبرمجة بواسطة لغة برمجة غرضية التوجه مثل Java أو C#

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

لنفترض اننا نريد برنامج صغير يقوم بالتعامل مع بيانات موظف وتخزينها على قاعدة بيانات وتعديل بيانات هذا الموظف أو حذفها

وبالتالي فان الناتج لدينا بعد مرحلتي جمع المتطلبات والتي تتمثل هنا بماهية بيانات الموظف أي نسأل الشخص الذي يريد هذا البرنامج ماهي البيانات الخاصة بالموظف والتي تريد تخزينها

فيجيب مثلا( اسم الموظف – عمره – حالته العائلية – رقمه الوظيفي .....)

ونسأله ماهي الوظائف التي تريد القيام بها على هذا الموظف فيجيب مثلا(حفظ بيانات الموظف-تعديله – حذف موظف-بحث بواسطةالاسم-بحث بواسطة الرقم .....)

وبالتالي ينتج لدينا بعدما سبق أنه يجب ان يكون لدينا صف يدعى Employee وهذا الصف له

Data Member هي (EmplyeeID,EmployeeName,EmployeeAge……)

ولهذا الصف Method وهي (saveEmployee-UpdateEmplyee-FindEmployeeByName...)

وبالتالي نقوم بانشاء الطبقات والتي ستسهل علينا عملية البرمجة بشكل كبير جدا حيث يكون لدينا هنا ثلاث طبقات كل طبقة تطلب خدمة من الطبقة التى هي أدنى منها

1- طبقة الواجهة :

والتي هي عبارة عن الواجهة التي سيتم ادخال البيانات عن طريقها أي تمثل الواجهة التي سيتعامل معها مستخدم البرنامج والتي تحوي على جميع العناصر المرئية

(TextBoxs , RadioButton,grid……)

وتحتوي ايضا على ازرار الحفظ والتعديل .......

2- طبقة الصفوف :

والتي تتضمن صف الموظف الذي تم استنتاجه قبل قليل

3- طبقة الدعم :

والتي تحوي على الصف الخاص بالاتصال بقاعدة البيانات بالإضافة الى أي صفوف مساعدة لاتنتمي للطبقات السابقة

ألية العمل:

عندما يقوم المستخدم بادخال البيانات عن طريق طبقة الواجهة ومن ثم يقوم بالضغط على زر الحفظ مثلا وعندها نقوم في الكود المكتوب في زر الحفظ بانشاء كائن (Object) من الصف الموظف (From Class Employee) ونقوم بعد إنشاء هذا الكائن بتمرير البيانات إلى الData Member الخاصة بالكائن الجديد ومن ثم نقوم باستدعاء طريقة الحفظ ( save Method) من خلال هذا الكائن الذي قمنا بتعريفه

أي تكون الشيفرة كالتالي:

Employee Emp = new Employee();

Emp.EmployeeID=TxtEmpID.Text.ToString();

…………………..

Emp.save();

وتقوم الشيفرة الخاصة بالمنهج Save بانشاء كائن من الصف الخاص بالاتصال بقاعدة البيانات والذي هو في طبقة الدعم ولنفترض ان اسم هذا الصف هو DBConnection ويكون الباني (Constructor) الخاص بهذا الصف مسؤول عن فتح الاتصال بقاعدة البيانات ولنفترض اننا قمنا بانشاء كائن (Object) من هذا الصف

DBConnection EmpConn = new DBConnection("Connection String"):

نقوم بتمرير البيانات المخزنة في الغرض السابق Emp إلى الغرض الذي قمنا بانشائه من صف الDBConnection ومن ثم نقوم بالتخزين على قاعدة البيانات بشكل عادي ولكن تكون التعليمات الخاصة بالحفظ على قاعدة البيانات داخل صف الDBConnection

وفي هذه الحالة عند التعديل لن نحتاج الى وقت كثير فمثلا اذا اردنا ان نضيف الى بيانات الموظف الراتب مثلا فلن نحتاج الى الكثير

أو لنفترض الحالة الأصعب أننا نريد الانتقال من قاعدة بيانات SQL Server إلى Oracle في هذه الحالة لن نحتاج سوى التعديل في صف الDBConnection

في الحقيقة ان الموضوع اكبر من مقالة صغيرة أكتبها ولكن عبارة عن لمحة موجزة أو مجرد تحفيز للمبرمجين ليتعرفوا على هذه الطريقة الرائعة

#2

اشكرك جدا على هذا الموضوع المهم؛؛ ولكن ي تعليق بسيط:

اقتباس
3- مرحلة التصميم ووتتضمن تحويل المعلومات التي حصلنا عليها في مرحلة التحليل عبر خطوات منظمة إلى ان ينتج معنا في النهاية صفوف ((Classes بجميع الطرق (Methods) الخاصة بهذه الصفوف وجميع المتحولات (Data Member) أيضاً

في هذه المرحلة يتم تصميم ال Interfaces وليس ال Classes؛؛ والمرحلة التي بعدها نأتي لل implementation وهي مرحلة بناء ال classes .

وشكرا مرة اخرى على هذا الموضوع.

اسف سوف اقطعك من كتابة الكود، ادخل هنا لدقيقتين فقط

http://www.shbab1.com/2minutes.htm

#3

أولا شكرا علي الموضوع ,

ثانيا : أنا أتساءل لماذا نقوم بتصميم الـ Interface ثم عمل Implementaion لها في الـ Class,

ما الفائده من ذلك ؟

#4

اهلا بك اخي hazzoom معنا في منتدى الجافا.

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

وللاجابة على سؤالك دعني اضع لك سيناريو معين:

بدأت في مشروع وجمعت المتطلبات ثم بعد ذلك بدأت بكتابة ال classes؛ وهناك مجموعة اخرى تعمل كلاسات اخرى؛

انت عملت كلاس اسمه Employee.

وهم عملوا كلاس اسمه DBConnection.

داخل الكلاس DBConnection هناك طريقة:

void add(Employee emp){}

دعني اسألك سؤال:

كيف سيعرف من قام بعمل DBConnection ماهي الطرق المتوفرة في الكائن emp؟؟

لن يعرفوها الا بعد ان تنتهي انت من عمل Employee class واعطاؤهم القائمة باسماء الطرق ووصفها.

ولكن اذا كان هناك interface قد عملت قبل البدء بكتابة الشفرة البرمجية؛ فسوف تبدأ كل مجموعة بكتابة ماعليها دون الحاجة للانتظار.

ملاحظة: عندما نقول interface فيمكن ان تكون عن طريق الشفرة؛ يعني نقوم بكتابة interface برمجيا؛ او ان تكون مجرد رسم عن طريق UML او اي شئ اخر وبذلك تعرف كل مجموعة ماذا يجب عليها.

طبعا انا هنا اتكلم من ناحية هندسة البرمجيات؛ اما في الامور البرمجية؛ فهناك فوائد للواجهات التي لاتخفى عليك.

اسف سوف اقطعك من كتابة الكود، ادخل هنا لدقيقتين فقط

http://www.shbab1.com/2minutes.htm

#5

استخدام الInterfaces دائما يستخدم عندما تريد أن تضيف صفة لمجموعة من الClasses..

مثلاً اذا كنت تريد أن تصنع Class تصف مدفع Cannon و تريد أن تجعل المطور أن يطور الClasses الخاصة بالطلقات الخاصة بالمدفع كما يريد و لكن يجب ان تكون هذه الclasses لها بعض السمات الأساسية (صفات) مثلاً ان تحتوي على function باسم Fire بحيث انك تستطيع أن تستخدم myBomb.Fire فيمكنك أن تقوم بعملInterface يسمى IShotable (أو قابل للاطلاق) و حرف الI كناية عن الInterface

و يكون IShotable بهذا الشكل

interface IShotable
{
void Fire();
}

على سبيل المثال

و في الCannon Class

public class Cannon
{
IShotable[] myBombs;
public Cannon(IShootable[] bombs)
{
this.myBombs = bombs;
}
public void FireCannon()
{
foreach(IShootable bomb in myBombs)
bomb.Fire();
}
}

و كما لاحظت فأنت لم تقم بعمل Implementation للFunction الخاصة بFire و لكن افترضت (و فرضت) و جودها في الobject القابل للاطلاق و هنا يجب على الDeveloper أن يقوم بعمل هذا

public Bomb : IShootable
{
public overrides void Fire()
{
//يكتب هنا مايجب أن يحدث عند اطلاق الطلقة
}
//يمكن أن تحتوي الكلاس على أي دوال او خصائص أخرى 
}

و هنا في البرنامج سيكتب المبرمج

Bomb[] myBombs = new Bomb[10];
myBombs.Initialize();
Cannon myCannon = new Cannon(myBombs);
myCannon.FireCannon();

الكود مكتوب بالSyntax الخاص بال#C و لكن الفرق ليس كبيراً و الغرض من الكود ليس الSyntaX بل المفهوم الأساسي البيسط للInterface

Sr. Software Development Engineer
Hulu, LLC
My Blogs

#6

شكرا لردك أخي فيصل , و قسم الجافا منور برواده :rolleyes:

يا أخ bashmohandes الـ Syntax بتاعت الـ #C توهتني :wacko:

ومش فاهم قصدك ايه :(

تم تعديل هذه المشاركة بواسطة hazzoom في 25 أكتوبر 2005 في 02:56

#7
hazzoom كتب:
يا أخ bashmohandes الـ Syntax بتاعت الـ #C توهتني  :wacko:

ومش فاهم قصدك ايه  :(

تحب الكود يتكتب بلغة ايه ؟؟؟

Sr. Software Development Engineer
Hulu, LLC
My Blogs

#9

اشوف منتدى جافا صار منتدى دوت نت :o

ايش عندهم الشباب سهرانين الى الان؛ يالله كل واحد يشرب الحليب ويروح غرفته ينام (h) (h)

اسف سوف اقطعك من كتابة الكود، ادخل هنا لدقيقتين فقط

http://www.shbab1.com/2minutes.htm

#10

السي شارب دوختك؟ تعال شوف السي! :lol: و لا السي بلص بلص .. لسة مش حتعرف راسك من رجلك .. :P

جماعة الفيبي دائما حابسين نفسهم بقوقعة الفيبي و ما يريدون يطلعون منها! مع العلم اني سمعت انه مع vb.net اصبحت لغة فيبي قريبة من سي شارب! فما بالك بمن لا يزال متقوقعا في الـ vb6!!

عموما, الموضوع انحرف عن مساره, و يجب تصحيحه ..

أولا شكرا على المقالة, و لي تعليق سريع فقد لفت نظري أمر ما:

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

لنفترض اننا نريد برنامج صغير يقوم بالتعامل مع بيانات موظف وتخزينها على قاعدة بيانات وتعديل بيانات هذا الموظف أو حذفها

وبالتالي فان الناتج لدينا بعد مرحلتي جمع المتطلبات والتي تتمثل هنا بماهية بيانات الموظف أي نسأل الشخص الذي يريد هذا البرنامج ماهي البيانات الخاصة بالموظف والتي تريد تخزينها

فيجيب مثلا( اسم الموظف – عمره – حالته العائلية – رقمه الوظيفي .....)

ونسأله ماهي الوظائف التي تريد القيام بها على هذا الموظف فيجيب مثلا(حفظ بيانات الموظف-تعديله – حذف موظف-بحث بواسطةالاسم-بحث بواسطة الرقم .....)

وبالتالي ينتج لدينا بعدما سبق أنه يجب ان يكون لدينا صف يدعى Employee وهذا الصف له

Data Member هي (EmplyeeID,EmployeeName,EmployeeAge……)

ولهذا الصف Method وهي (saveEmployee-UpdateEmplyee-FindEmployeeByName...)

كلام جميل, لكن التطبيق لا يتبع الكلام, فكلاس الموظف من المفروض ان لا علاقة له بحفظ الموظف في الملف, و لا علاقة له بالبحث عن الملف, لان هذه الأمور يجب ان تكون من مهام كلاسات أخرى .. و الا فلا معنى لفصل الطبقات.

لما تفصل التطبيقات بشكل جيد, سيكون كلاس الموظف مسؤول فقط عن الاحتفاظ بمعلومات الموظف, و ليس شيء آخر! اذا اردت البحث عن الموظف فيجب ان يكون هناك كلاس آخر عبارة عن قائمة موظفين, و هناك يمكن تطبيق عمليات البحث و الحذف .. الخ.

و كذلك عملية تخزين البيانات الى ملف, يجب ان تكون من مهمة كلاس آخر, مثلا EmployeeFile او شي من هالقبيل ..

قد يقول البعض ان هذا تعقيد, و لكن هكذا هي هندسة البرمجيات, و انظر الى اي مشروع كبير الحجم, و ستجد كما هائلا من الكلاسات معظمها يدور حول نفس الكائن, مثلا في Eclipse هناك يمكن اقل شي عشر كلاسات مرتبطة بمحرر النصوص ..

#11

المشكله يا أخ حسن في اختلاف المرادفات وكده يعني ,

ثانيا يا عم حسن أنا غلبان ومش قدك , ولا قد السي وناسها ,,,

#12

وجهة نظر،، كان من الأفضل أن تكون الواجهات لا تبدأ بحرف I وذلك لأنها تستخدم أكثر من الفئات Classes،

ولو كان ولا بد التمييز، لوضعت C للإشارة إلى الفئة ، ولم أضع حرفا للواجهة!!

#13

هل تعلمون ان هناك الاف المبرمجين المعارضين لفكرة البرمجة الشيئية؟!! والسبب هو صعوبة التصميم.

قرأت في احدى منتديات الانترنت معركة كبيرة بين المؤيدين والمعارضين؛ ولكن للاسف لم يصلوا الى نتيجة.

كانت حجة المعارضين: ان الصعوبة في فهم OOP تجعلها شئ غير مرغوب فيه. وايضا لهم حجة اخرى: ان حتى المبرمجين الخبيرين في OOP يخطئون دوما في تصميم كلاساتهم.

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

شئ اخر لفت انتباهي؛ كثير من البرمجين المحترفين يعارضون حتى فكرة ال extends ويحبذون implements .

اقرأ هذا المقال الذي لفت انتباهي:

Why extends is evil

لاأدري تصدق من؛ في هذا الموضوع الشائك.

تم تعديل هذه المشاركة بواسطة فيصل الردادي في 25 أكتوبر 2005 في 11:24

اسف سوف اقطعك من كتابة الكود، ادخل هنا لدقيقتين فقط

http://www.shbab1.com/2minutes.htm

#14

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

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

بالمناسبة, احد استذتنا كان مجنون oop :P و هو لا يحب الـ interface :lol:

تم تعديل هذه المشاركة بواسطة hasan_aljudy في 25 أكتوبر 2005 في 14:46

#15

أخ فيصل،، من المؤكد وجود الآلاف من يعارض استخدام البرمجة غرضية التوجه! وأعتقد أن 99% منهم لا يدرك كيف يستخدمها بصراحة،، خذ المثال التالي، لو سألت المبرمجين عن أفضل لغة لقالوا لك VB لأن أكثرهم مبرمجون لهذه اللغة ولا يعرفوا غيرها وسيعارضون أي جديد!

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

لكن المسألة ليست في الوراثة،، تخيل مثلا أن عندك هذه الواجهة :

public interface Lamp{
public void open();
public boolean close();
}

وافترض أنك صنعت 20 مصباحا مختلفا، طبعا صنعت بذلك 20 فئة جديدة!

الآن عندما تبدأ تطوير برنامج ما،، أدركت أنك تحتاج إلى وظيفة أخرى وهي: isOpen، ماذا ستفعل؟؟

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

أما لو أضفت طريقة جديدة مثل isOpen في فئة ليست واجهة، فلن تضطر إلى تغيير شيء في الفئات التي ترث من Lamp!!

طبعا أعود وأقول لكل ميزة، ولكل هدف!

ومع وجود هذه العقبات، فإن هذا الأسلوب أفضل ب 60 مرحلة مما كنا عليه من غير الشيئية التوجه!! دعني لا أتكلم عن اللغات الهندسية وما فيها من مشاكل!

--

حسن: كيف لا يحب الواجهات وهي لب OOP?

#16

إن مسألة حب الـ OOP أو عدمه، مسألة نسبية. ولكن الهدف من OOP منذ ظهوره هو تسهيل التطوير وليس تصعيبه. فإذا كان برنامجك صغيراً جداً لدرجة أنه قد لا يحوي إلى class واحد فربما يكون استخدام غرضية التوجه هنا أمر مهلك، وربما يكون استخدام VB هو الأفضل لأن VB تدعم ((عدم)) غرضية التوجه، لا حظوا ((عدم)) أي عكس بقية اللغات.

ولكن في أغلب الأحوال، استخدام غرضية التوجه في البرمجة أصبح أمر مفروغ من أهميته. فتخيل شيفرة من دون comments هل ستفهم شيء؟؟؟ ربما تقول نعم، ولكن الأمر سوف يكون صعباً جداً.

وكدليل على مدى أهمية غرضية التوجه أن VB تطورت من VB6 إلى VB.NET لتدعم غرضية التوجه بكافة معانيها. حتى أن غرضية التوجه الآن لم تعد مقتصرة على البرمجة كما نعرف، فبما أن الموضوع هنا هو هندسة البرمجيات، فالنرى أن غرضية التوجه قد أصبحت في التصمي OOD والتحليل OOA وغيرها من أمور هندسة البرمجيات. ربما لم يبقى إلا أن نقول هندسة برمجيات غرضية التوجه OOSE ـ Object Oreinted Software Engineer.

(ستخدامت كلمة غرضية بدلاً من شيئة لأن هذا ما اعتدت عليه. :wacko: )

#17

أبو مازن: لأن صاحبنا من جماعة small talk و هي لغة فيها dynamic typing يعني لا تحتاج لتعريف انترفيس .. تستطيع اخذ اي كائن و ارسال اي رساله له, حتى لو لم يكن لدى هذا الكائن استجابة لهذه الرسالة .. لذلك صاحبنا يعتقد ان الانترفيس هي من تعقيدات اللغات اللتي فيه static typing

#18

أهاا،، smalltalk مثل python...

عموما،، مدرسك يقصد تعريف الواجهة وليس المبدأ،، فهي فعلا تعقيد بالنسبة إلى dynamic typing،،

بالمناسبة،، اللغة البسيطة التي صممتها هي dynamic typing!!

،،

#19

حبيايبي الانترفيس ميزه ايجابية وليست سلبية كما اشار البعض منك : انا بعطيكم الفكرة الاساسيه

لنفرض ان عندنا ثلاث كلاسات : مربع ومثلث و دائره

كلنا بنلاحظ انه فيه عده صفات مشتركة بينها على سبيل المثال : المساحة (مع العلم انه لكل كلاس طريقة لحساب المساحه)

اذا كنا بنكتب برنامج لحساب المساحة

الطريقة الوحيدة لاجبار الكلاسات على احتواء هذة الخاصية هي عبر تصميم انترفيس اسمه: شكل

بحيث انه اي احد بيستخدم الانترفيس يجب عليه ان يعرف الطريقة داخل الكلاس(اي كلاس يستخدم انترفيس يجب عليه تعريف جميع الطرق(ميثود) داخل الانترفيس في الكلاس الجديد)

بعدين اذا جينا في البرنامج نقدر نستخدم اي اوبجكت بنفس الميثود والطريقه الصحيحه (اعتمادا على نوع الاوبجكت الطريقه الصحيحه لحساب المساحه) راح تتنفذ

#20
اقتباس
حبيايبي الانترفيس ميزه ايجابية وليست سلبية كما اشار البعض منك

ومن قال انها سلبية !!!!!!!

اسف سوف اقطعك من كتابة الكود، ادخل هنا لدقيقتين فقط

http://www.shbab1.com/2minutes.htm

مواضيع مشابهة