قبل ما نبدأ رحلتنا في تطور كتابة الأكواد، خلينا نفهم الأول إن فيه طرق تفكير وأساليب مختلفة بنكتب بيها البرامج، الطرق دي بنسميها Programming Paradigms (نماذج البرمجة).
أشهر النماذج دي هي: (Imperative)، (Declarative)، (Object-Oriented - OOP)،(Functional). يلا نشوف إزاي تطورنا من طريقة للتانية وإيه علاقة ده بالـ C#.
1. البدايات: Imperative Programming
في الأول خالص،في الـ Linear Code وبعدين الـ Structured Programming، كنا بنكتب الكود بطريقة أمرية (Imperative).
- يعني إيه Imperative؟ يعني بنركز على “إزاي” (How) ننفذ المهمة. بندي للكمبيوتر مجموعة أوامر وتعليمات واضحة ورا بعض، خطوة بخطوة، عشان نغير حالة البرنامج (state) ونوصل للنتيجة المطلوبة.
- الـ Linear (Procedure) Code: كان أبسط شكل للـ Imperative، عبارة عن أوامر متتالية وخلاص. ده كان بيؤدي لمشاكل كتير زي:
- تكرار كتير جدًا في الكود.
- صعوبة وتكلفة التعديل العالية جدًا.
- الكود بيبقى عامل زي السباجيتي (spaghetti code)، صعب تتابعه وتفهمه.
- مفيش تنظيم حقيقي (لا function ولا class).
- الـ Structured Programming: دي كانت تحسين للـ Imperative.
- بدأنا نقسم الكود لأجزاء أصغر ومنظمة أكتر باستخدام الـ Function (أو procedures).
- استخدمنا هياكل تحكم واضحة (زي
if
,for
,while
). - ده قلل التكرار وحسّن التنظيم (زي ما شوفنا في لغة C)، لكن لسه فيه مشاكل:
- الـ Global variables كانت لسه بتعمل لخبطة وصعب تتبعها.
- الـ Stand alone function: يعني function كده لوحدها مش متجمعة جوه كيان أكبر ليه معنى واضح زي الـ class اللي هييجي بعدين.
- الكود لسه بيركز على “إزاي” نعمل الحاجة خطوة بخطوة.
- الـ Linear (Procedure) Code: كان أبسط شكل للـ Imperative، عبارة عن أوامر متتالية وخلاص. ده كان بيؤدي لمشاكل كتير زي:
2. النقلة الكبيرة:Object-Oriented Programming - OOP
هنا بقى حصل تغيير كبير في طريقة التفكير والتنظيم:
- الـ OOP (زي ما شفنا في لغات زي Smalltalk, C++, Java, C#) نقلت التركيز من مجرد “الأوامر” لـ (Objects).
- الوحدة الأساسية هي الـ Class، اللي هو زي تصميم أو قالب بنعمل منه الـ Objects.
- الـ Class بيجمع Data (الخصائص أو الـ attributes) و Methods (السلوك أو الأفعال اللي الـ object يقدر يعملها) مع بعض في مكان واحد.
- ليه الـ OOP عمل النقلة دي؟ عشان مفاهيمه الأساسية بتحل مشاكل كتير:
- الـ Encapsulation (التغليف): إخفاء التفاصيل الداخلية للـ class وحماية الـ data بتاعته، وده بيخلي الصيانة أسهل. (زي مثال سفرة الأكل المتغطية).
- الـ Inheritance (الوراثة): السماح لـ class إنه ياخد خصائص وسلوكيات class تاني، وده بيشجع على إعادة الاستخدام (Reusability).
- الـ Polymorphism (تعدد الأشكال): قدرة الـ objects إنها تتصرف بطرق مختلفة حسب السياق، وده بيدي مرونة (Flexibility) للتصميم.
- ملاحظة: رغم إن الـ OOP بينظم الكود بشكل مختلف، إلا إن الكود اللي جوه الـ methods غالبًا بيكون لسه imperative (يعني خطوات وأوامر).
تاريخ اختراع لغة الـ C# وتطورها
- زمان، كانت لغة Smalltalk من أوائل اللغات اللي طبقت الـ OOP. بس كان صعب على المبرمجين اللي شغالين بلغة C إنهم ينقلوا فجأة للغة تانية زي دي.
- عشان كده، عملوا لغة تانية اسمها C++. هي هياها لغة C بس زودوا عليها مفاهيم الـ OOP.
- بس في الحقيقة، لغة C++ تعتبر Not pure OOP (يعني مش OOP صافية 100%).
- لإنك جواها تقدر تكتب كود C عادي (يعني ممكن تعمل Stand alone function و global variable) وتقدر كمان تكتب OOP.
- بعد كده، شركة Sun Microsystems عملت لغة Java.
- لغة Java حاولت تقرب أكتر لفكرة الـ Pure OOP. عشان كده مفيش فيها Global Variable ولا Stand alone functions بره أي Class. أي كود لازم يكون جوه Class.
- (برضه لازم نكون دقيقين، كلمة Pure OOP دي عليها تحفظ شوية، لإن Java نفسها فيها حاجات مش Objects بالكامل زي الـ primitive types، بس لو قارناها بـ C++، فالـ Java ملتزمة أكتر بالـ OOP).
- وبعدين شركة Oracle اشترت شركة Sun.
- شركة Microsoft كمان كانت عايزة تعمل لغة Pure OOP. فخدوا الأفكار من الـ C والـ C++.
- عملوا لغة اسمها Cool (اللي هي اختصار لـ C like object oriented language). بس الاسم ده مكنش جذاب في السوق.
- فكروا يسموها C++++ (أربعة زائد)، بس برضه مكنش اسم كويس.
- ومن هنا طلع اسم C#. لإن علامة الشباك (#) لو ركزت فيها هتلاقيها شبه أربع علامات ”+” (زائد) فوق بعض وجنب بعض.
- لغة C# اتعملت سنة 2000، وتاني version منها كان سنة 2005، وهي بتعتبر Pure OOP (بالمقارنة مع C++).
- برضه للتوضيح، هي مش Pure 100% بالمعنى الحرفي الدقيق، لإن لسه فيها value types (زي
int
,bool
…) اللي مش Objects بالكامل. لكن بالمقارنة مع C++، هي فعلًا أجبرتك تحط كل الـ code جوه Classes ومافيش حاجة اسمها Functions standalone بره الـ Classes. فلو قصدنا إنها أكتر التزامًا بالـ OOP من C++، فده يعتبر كلام صح بشكل كبير.
- برضه للتوضيح، هي مش Pure 100% بالمعنى الحرفي الدقيق، لإن لسه فيها value types (زي
- نقطة مهمة عن C#: لغة C# (ومعاها كل بيئة الـ .NET) بتعتبر Managed Code. ده معناه إن الكود بتاعك مش بيشتغل مباشرة على الـ Hardware، لأ، ده بيشتغل جوه بيئة خاصة اسمها CLR(Common Language Runtime). الـ CLR دي بتدير حاجات كتير بالنيابة عنك، أهمها الـ Memory Management (إدارة الذاكرة) عن طريق الـ Garbage Collector (جامع القمامة اللي بينضف الميموري لوحده)، وكمان بتوفر طبقة أمان وحماية أعلى. ده فرق كبير عن لغات زي C++ اللي بتتعامل فيها مع الميموري بشكل مباشر (بيتقال عليها Unmanaged Code).
3. طريقة تفكير مختلفة: Declarative Programming
على عكس الـ Imperative اللي بيركز على “إزاي”، الـ Declarative Programming بيركز على “إيه” (What) اللي إحنا عايزينه كنتيجة نهائية، من غير ما نحدد الخطوات بالتفصيل.
- إحنا بنوصف الهدف أو الشكل المطلوب، واللغة أو النظام هو اللي بيعرف إزاي يوصل للنتيجة دي.
- أمثلة مشهورة:
- علاقتها بـ C#: هنشوف إن C# الحديثة فيها أجزاء بتستخدم أسلوب declarative، زي LINQ.
4. التركيز على الدوال: Functional Programming - FP
ده نموذج برمجة تاني مهم وليه فلسفته الخاصة:
- الـ Functional Programming (FP) بيتعامل مع العمليات الحسابية كأنها تقييم لدوال رياضية (mathematical functions).
- المبادئ الأساسية:
- الـ Pure Functions (الدوال النقية): الدالة اللي دايمًا بترجع نفس الناتج لنفس المدخلات، ومبتأثرش على أي حاجة براها (No side effects).
- الـ Immutability (عدم القابلية للتغيير): البيانات مينفعش تتغير بعد ما تتعرف. لو عايز تغير حاجة، بتعمل نسخة جديدة بالتغيير المطلوب.
- الـ Functions as First-Class Citizens: الدوال بتتعامل زي أي متغير عادي، تقدر تبعتها كـ parameter لدوال تانية، أو ترجعها كنتيجة من دالة، أو تخزنها في متغير.
- الـ Avoiding State Changes: بنحاول على قد ما نقدر نتجنب تغيير حالة البرنامج.
- مميزاته: الكود بيكون أسهل في الفهم والتوقع والاختبار، وبيبقى مناسب أكتر للتعامل مع الـ Concurrency (تشغيل كذا حاجة في نفس الوقت).
- علاقته بـ C#: لغات زي C# مبقتش بس OOP، لأ دي بقت Multi-Paradigm Language، يعني بتدعم أكتر من نموذج برمجة. C# الحديثة فيها دعم قوي لمفاهيم كتير من الـ FP:
- الـ Cs Lambda Expressions: طريقة مختصرة لكتابة الدوال.
- الـ LINQ (Language Integrated Query): ده مثال قوي على الأسلوبين (Functional & Declarative) جوه C# عشان تتعامل مع البيانات.
- الـ Immutability: بقينا بنشوف دعم أكبر للـ immutable types في .NET.
- الـ Pattern Matching: طرق أسهل للتعامل مع أشكال البيانات المختلفة.
مثال للفرق بينهم في تنظيم الشغل (سفرة الأكل)
- تخيل إننا قاعدين على سفرة أكل، وفيه أكلات معينة قدامنا (دي تعتبر زي الـ Methods).
- لو كل واحد مد إيده ياخد اللي هو عايزه على طول (أسلوب Imperative مباشر أو Structured مع global variables)، هتحصل لخبطة.
- إنما لو غطينا كل طبق، وعشان تاخد منه لازم تستخدم طريقة معينة (زي الـ public methods في الـ OOP اللي بتعمل Encapsulation)، فده بيخلي الدنيا منظمة أكتر.
الخلاصة والتطور المستمر…
رحلة البرمجة بدأت بأسلوب Imperative بسيط وخطوة بخطوة، ثم تطورت لـ Structured Programming لتنظيم أفضل، ثم قفزت قفزة كبيرة مع الـ OOP اللي ركز على الكائنات والتغليف والوراثة. بالتوازي، كان فيه أساليب تانية زي الـ Declarative اللي بيركز على “الإيه” مش “الإزاي”، والـ Functional Programming اللي بيركز على الدوال وتجنب تغيير الحالة.
اللغات الحديثة زي C# مبقتش محصورة في نموذج واحد، لكن بقت بتجمع أحسن ما في كل نموذج (Multi-Paradigm) عشان تدي للمبرمج أدوات أكتر قوة ومرونة يبني بيها تطبيقات معقدة وقابلة للصيانة والتطوير. وفهم النماذج المختلفة دي بيخليك مبرمج أشطر وتقدر تختار الأسلوب الأنسب للمشكلة اللي بتحاول تحلها.
// Example showing different paradigms coexisting in C#
using System.Linq; // Needed for LINQ (Declarative/Functional)
using System.Collections.Generic; // For List (OOP)
public class Example // OOP: Class definition
{
// OOP: Data member (field)
private List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6 };
// OOP: Method (often contains Imperative code inside)
public void PrintEvenNumbersImperative()
{
System.Console.WriteLine("Even Numbers (Imperative):");
// Imperative: Looping step-by-step, checking condition
foreach (int number in numbers)
{
if (number % 2 == 0)
{
System.Console.WriteLine(number);
}
}
}
// Declarative/Functional approach using LINQ
public void PrintEvenNumbersDeclarative()
{
System.Console.WriteLine("Even Numbers (Declarative/Functional with LINQ):");
// Declarative: Describe *what* you want (even numbers)
// Functional: Using Where (higher-order function), Lambda expression
var evenNumbers = numbers.Where(n => n % 2 == 0);
// Imperative: Still need a loop to print, but the filtering was declarative
foreach (int number in evenNumbers)
{
System.Console.WriteLine(number);
}
}
}