




السمعة:
- إنضم22 ديسمبر 2023
- المشاركات 192
- الحلول 1
- مستوى التفاعل 288
- النقاط 63
بسم الله الرحمن الرحيم
السلام عليكم ورحمة الله وبركاته
سنكمل اليوم في سلسلة "ما الفرق؟" ودرسنا لهذا اليوم سيكون عن المقارنة بين البرمجة الهيكلية (Procedural Programming) والبرمجة الكائنية (Object-Oriented Programming)
في منتصف القرن الماضي، تحديدًا في الخمسينيات والستينيات من القرن العشرين، كانت البرمجة تعتمد بشكل رئيسي على أسلوب يُعرف بـ "البرمجة الإجرائية غير المنظمة" هذا الأسلوب يعتمد على تنفيذ الأوامر والخطوات البرمجية بشكل متسلسل دون هيكل واضح، وكانت تُستخدم أوامر للانتقال بين أجزاء مختلفة من البرنامج مثل أمر {goto} ولكن هذه الطريقة تسببت في العديد من المشاكل، مثل التعقيد في صيانة البرنامج خصوصًا إذا كان حجم البرنامج كبيرًا، وأيضًا صعوبة في فهمه بسبب الانتقالات العشوائية بين الأجزاء المختلفة من الكود باستخدام {goto} كما أن الأخطاء كانت تحدث بكثرة بسبب هذه الانتقالات غير المتوقعة.
هنا دعت الحاجة إلى تقديم أسلوب جديد في البرمجة لتجنب التعقيد وتحسين الصيانة، وهذا ما قام به إدسغر ديكسترا حيث قدم منهجية جديدة تعتمد البرمجة الهيكلية بدلاً من البرمجة الإجرائية غير المنظمة بحيث يكون هناك تسلسل منطقي للبرنامج دون استخدام أوامر مثل {goto} وذلك عن طريق استخدام هياكل تحكم مثل الحلقات الشرطية (... ,if, while) لتسهيل تدفق البرنامج. كما أن هذه المنهجية تقوم بتقسيم البرنامج إلى ما يُعرف بالدوال (functions) بحيث يتم فهم وصيانة كل قسم على حدة ببساطة وسهولة.
مع تطور البرمجيات في السبعينيات والثمانينيات، بدأت البرامج تصبح أكثر تعقيدًا وتشمل مكونات وأجزاء متعددة. استخدام البرمجة الهيكلية كان فعالًا، لكنه بدأ يواجه تحديات جديدة مثل مشكلة تكرار الكود، حيث لم يكن هناك طريقة فعالة لإعادة استخدام الكود في البرمجة الهيكلية لذا كان على المطورين كتابة الكود مرارًا وتكرارًا لأداء نفس المهام، وأيضًا التعامل مع البيانات في البرمجة الهيكلية بشكلٍ منفصل عن الوظائف أدى إلى صعوبة التوسع وإعادة استخدام الكود، عدا عن أنها غير مرنة بشكل كافٍ للتعامل مع حالات الكائنات في الأنظمة المعقدة مثل البرمجيات الرسومية أو الألعاب.
وهنا ظهرت البرمجة الكائنية كتطور للبرمجة الهيكلية لتلبية هذه الاحتياجات وتوفير وسائل أكثر فعالية لإدارة البيانات والسلوكيات المرتبطة بها من خلال الكائنات والمفاهيم المرتبطة بها، والتي سنتحدث عنها في هذا الدرس إن شاء الله.
الآن لنتعرف على كل من النوعين بالتفصيل، بسم الله نبدأ:
السلام عليكم ورحمة الله وبركاته
سنكمل اليوم في سلسلة "ما الفرق؟" ودرسنا لهذا اليوم سيكون عن المقارنة بين البرمجة الهيكلية (Procedural Programming) والبرمجة الكائنية (Object-Oriented Programming)
في منتصف القرن الماضي، تحديدًا في الخمسينيات والستينيات من القرن العشرين، كانت البرمجة تعتمد بشكل رئيسي على أسلوب يُعرف بـ "البرمجة الإجرائية غير المنظمة" هذا الأسلوب يعتمد على تنفيذ الأوامر والخطوات البرمجية بشكل متسلسل دون هيكل واضح، وكانت تُستخدم أوامر للانتقال بين أجزاء مختلفة من البرنامج مثل أمر {goto} ولكن هذه الطريقة تسببت في العديد من المشاكل، مثل التعقيد في صيانة البرنامج خصوصًا إذا كان حجم البرنامج كبيرًا، وأيضًا صعوبة في فهمه بسبب الانتقالات العشوائية بين الأجزاء المختلفة من الكود باستخدام {goto} كما أن الأخطاء كانت تحدث بكثرة بسبب هذه الانتقالات غير المتوقعة.
هنا دعت الحاجة إلى تقديم أسلوب جديد في البرمجة لتجنب التعقيد وتحسين الصيانة، وهذا ما قام به إدسغر ديكسترا حيث قدم منهجية جديدة تعتمد البرمجة الهيكلية بدلاً من البرمجة الإجرائية غير المنظمة بحيث يكون هناك تسلسل منطقي للبرنامج دون استخدام أوامر مثل {goto} وذلك عن طريق استخدام هياكل تحكم مثل الحلقات الشرطية (... ,if, while) لتسهيل تدفق البرنامج. كما أن هذه المنهجية تقوم بتقسيم البرنامج إلى ما يُعرف بالدوال (functions) بحيث يتم فهم وصيانة كل قسم على حدة ببساطة وسهولة.
مع تطور البرمجيات في السبعينيات والثمانينيات، بدأت البرامج تصبح أكثر تعقيدًا وتشمل مكونات وأجزاء متعددة. استخدام البرمجة الهيكلية كان فعالًا، لكنه بدأ يواجه تحديات جديدة مثل مشكلة تكرار الكود، حيث لم يكن هناك طريقة فعالة لإعادة استخدام الكود في البرمجة الهيكلية لذا كان على المطورين كتابة الكود مرارًا وتكرارًا لأداء نفس المهام، وأيضًا التعامل مع البيانات في البرمجة الهيكلية بشكلٍ منفصل عن الوظائف أدى إلى صعوبة التوسع وإعادة استخدام الكود، عدا عن أنها غير مرنة بشكل كافٍ للتعامل مع حالات الكائنات في الأنظمة المعقدة مثل البرمجيات الرسومية أو الألعاب.
وهنا ظهرت البرمجة الكائنية كتطور للبرمجة الهيكلية لتلبية هذه الاحتياجات وتوفير وسائل أكثر فعالية لإدارة البيانات والسلوكيات المرتبطة بها من خلال الكائنات والمفاهيم المرتبطة بها، والتي سنتحدث عنها في هذا الدرس إن شاء الله.
الآن لنتعرف على كل من النوعين بالتفصيل، بسم الله نبدأ:
التعريف | Definition


الاستخدامات | Uses








الخصائص | Characteristics

1. التقسيم إلى دوال: يتم تقسيم البرنامج إلى دوال أو إجراءات، وكل دالة تنفذ جزءًا من العمل.
2. التسلسل المنطقي: يعتمد على التسلسل المنطقي في تنفيذ التعليمات.
3. إعادة استخدام الكود: يمكن إعادة استخدام بعض الأجزاء من الكود في أماكن مختلفة، لكن بدرجة أقل من البرمجة الكائنية.

1. التقسيم إلى كائنات: يتم تقسيم البرنامج إلى كائنات تحتوي على بيانات ووظائف.
2. التجريد (Abstraction): يمكن إخفاء التفاصيل المعقدة وجعل البرمجيات أسهل للتطوير والفهم.
3. الوراثة (Inheritance): يمكن إنشاء فئات جديدة تعتمد على فئات موجودة مسبقًا.
4. التعددية (Polymorphism): القدرة على استخدام نفس الوظيفة بعدة طرق مختلفة.
المزايا والعيوب | Advantages and Disadvantages
للبرمجة الهيكلية (Procedural Programming) مزايا وعيوب لنستذكر أهمها:
المزايا: | العيوب: |
سهل التعلم والتطبيق في المشاريع الصغيرة. | صعوبة التعامل مع التعقيد في المشاريع الكبيرة، حيث يصعب التحكم في البيانات والحفاظ على تنظيم الكود. |
واضح ويتيح التحكم في تسلسل البرنامج | صعوبة توسيع البرنامج أو صيانته في حالة التغييرات. |
أما البرمجة الكائنية (Object-Oriented Programming - OOP) فلها مزايا وعيوب مختلفة تتمثل بـِ:
المزايا: | العيوب: |
تنظيم عالي للكود، مما يسهل صيانته وتوسيعه كما أنه مناسب للمشاريع المعقدة | أكثر تعقيدًا للتعلم مقارنة بالبرمجة الهيكلية. |
إعادة استخدام الكود بشكل أفضل باستخدام الوراثة. | قد تكون أقل فعالية في البرامج الصغيرة حيث يمكن أن تزيد من تعقيد البرنامج دون داعٍ. |

*في البرمجة الهيكلية (Procedural Programming): سنقوم بتقسيم البرنامج إلى دوال (functions) تؤدي مهام محددة. هنا ستتم معالجة كل كتاب كبيانات منفصلة من خلال دوال تقوم بإضافته أو حذفه أو تحديثه. بناءً على ذلك.
سنتقوم بتنفيذ هذا البرنامج باستخدام إحدى لغات البرمجة ولتكن لغة C.
C:
#include <stdio.h>
#include <string.h>
// Define the book's data structure
struct Book {
char title[100];
char author[100];
int id;
};
// Function to add a book
void addBook(struct Book *book, char title[], char author[], int id) {
strcpy(book->title, title);
strcpy(book->author, author);
book->id = id;
printf("The book has been added successfully\n");
}
// Function to print book information
void printBook(struct Book *book) {
printf("Book title: %s\n", book->title);
printf("book author: %s\n", book->author);
printf("Book ID: %d\n", book->id);
}
int main() {
struct Book myBook;
// Add a book
addBook(&myBook, "Structured programming", "Unknown author", 1);
// Print book information
printBook(&myBook);
return 0;
}
في هذا المثال قمنا بتعريف هيكل بيانات بسيط للكتاب باسم (struct) يحتوي على العنوان، المؤلف، والمعرف.
لدينا أيضًا دوال (functions) لإضافة كتاب جديد وطباعة معلومات الكتاب.
نلاحظ هنا أن البرنامج يعتمد على التسلسل الواضح والمباشر لتنفيذ المهام.
*أما في البرمجة الكائنية (Object-Oriented Programming - OOP): سنقوم بإنشاء فئة (class) تمثل الكتاب. كل كتاب سيُعبر عنه ككائن (object) يحتوي على خصائصه وسلوكياته. يمكننا توسيع البرنامج بسهولة بإضافة فئات جديدة لإدارة الكتب ولتكن باسم "Library" مثلاً.
سنتقوم بتنفيذ هذا البرنامج باستخدام إحدى لغات البرمجة ولتكن لغة ++C.
C++:
#include <iostream>
#include <string>
using namespace std;
class Book {
private:
string title;
string author;
int id;
public:
// Constructor to add a book
Book(string t, string a, int i) : title(t), author(a), id(i) {}
// Function to print book information
void printInfo() {
cout << "Book title : " << title << endl;
cout << "Book author: " << author << endl;
cout << "Book ID: " << id << endl;
}
};
class Library {
private:
Book* books[100];
int bookCount;
public:
Library() : bookCount(0) { }
// Add a new book to the library
void addBook(Book* newBook) {
books[bookCount++] = newBook;
cout << "The book has been added successfully\n";
}
// Show information for all books
void printBooks() {
for (int i = 0; i < bookCount; i++) {
books[i]->printInfo();
}
}
};
int main() {
// Create books
Book book1("Object-oriented programming", "Unknown author", 1);
Book book2("Systems design", "Another author", 2);
// Create a library
Library myLibrary;
// Add books to the library
myLibrary.addBook(&book1);
myLibrary.addBook(&book2);
// View book information
myLibrary.printBooks();
return 0;
}
في هذا المثال قمنا بإنشاء فئة (class) تمثل الكتاب تحتوي على الخصائص مثل العنوان، المؤلف، والمعرف، بالإضافة إلى دالة لطباعة المعلومات.
هناك أيضًا فئة أخرى للمكتبة (Library) التي تحتوي على مجموعة من الكتب حيث تقوم بإضافة كتب جديدة وتخزينها، وكذلك عرض جميع الكتب الموجودة.
نلاحظ هنا أننا تمكنا من توسيع البرنامج بسهولة بإضافة ميزات جديدة مثل إدارة الكتب.
وأخيرًا سأضع لكم جدولًا يلخص أهم الفروقات بين النوعين:
وجة المقارنة | البرمجة الهيكلية | البرمجة الكائنية |
التقسيم | البرنامج مقسم إلى دوال (Functions). | البرنامج مقسم إلى كائنات (Objects). |
التركيز | التركيز على الوظائف (Functions). | التركيز على البيانات والكائنات. |
إعادة الاستخدام | صعبة نسبيًا، تحتاج لكتابة الكود مجددًا. | سهلة باستخدام الوراثة وإعادة استخدام الكائنات. |
التعقيد | أقل تعقيدًا وأسهل للتعلم. | أكثر تعقيدًا وصعب للتعلم. |
المرونة | مرونة أقل في التعامل مع التغييرات. | مرونة عالية في التوسيع والتعديل. |
أمثلة عملية | برنامج حسابي بسيط، أو برنامج لمعالجة البيانات في ملف نصي | تصميم ألعاب الفيديو، تطوير تطبيقات الأعمال التجارية الكبيرة، أو أنظمة إدارة قواعد البيانات. |
مناسبة للمشاريع | البرامج الصغيرة المتوسطة. | البرامج الكبيرة المعقدة . |
من كان لديه أي إضافة على هذا الموضوع، أرجو منكم وضعها في التعليقات لإفادة الغير ونيل الأجر والثواب إن شاء الله.
وهكذا نكون قد أنهينا درسنا لهذا اليوم.
إن أصبت، ففضل من الله ومنه، وإن أخطأت، فمن نفسي ومن الشيطان.
لمتابعة هذه السلسلة من البداية والتعرف على أهم الفروقات في العالم الرقمي بشكل سلس وبسيط، إليك روابط الدروس السابقة:
1. الفرق بين CPU & GPU
2. الفرق بين البرمجة الأمامية والبرمجة الخلفية
3. الفرق بين Windows & Linux
4. الفرق بين الشبكات السلكية والشبكات اللاسلكية
والسلام عليكم ورحمة الله وبركاته