قبل ما نخش في تفاصيل الأكواد، لازم نفهم إن فيه طرق وأساليب تفكير مختلفة بنكتب بيها البرامج. الطرق دي بنسميها Programming Paradigm (نماذج البرمجة).

أشهر النماذج دي هي: Imperative، Declarative، Object-Oriented (OOP)، و Functional (FP) . يلا بينا نشوف إزاي الدنيا اتطورت من طريقة للتانية وإيه علاقة ده بلغة الـ C#.

graph TD
    subgraph "Main Paradigms"
        A[Imperative Programming]
        D[Declarative Programming]
    end

    subgraph "Imperative Evolution"
        direction LR
        A1(Unstructured) --> A2(Structured) --> A3(OOP)
    end
    
    subgraph "Declarative Styles"
        direction LR
        D1(Functional) --> D
        D2(Logic) --> D
        D3(Database/Query) --> D
    end

    subgraph "C# is Multi-Paradigm"
        E[CSharp]
    end

    A --> A1
    A3 --> E
    D --> E

    style A fill:#f9f,stroke:#333,stroke-width:2px
    style D fill:#9cf,stroke:#333,stroke-width:2px
    style E fill:#9f9,stroke:#333,stroke-width:4px

قبل ما نبدأ… نقطة مهمة جدًا:

النماذج البرمجية دي مش في حرب ضد بعض. يعني مش لازم تختار بين OOP أو Functional. في لغات حديثة زي C#، بنقدر نستخدم أكتر من نموذج في نفس المشروع، وكل واحد بيكون مفيد حسب الموقف.

البرمجة مش ديانة، ومفيش نموذج “أحسن من التاني”. كل واحد ليه طريقة تفكير بتحل نوع معين من المشاكل بكفاءة.

1. البدايات: الـ Imperative Programming

في الأول خالص، مع الـ Unstructured وبعد كده الـ Structured Programming، كنا بنكتب الكود بطريقة أمرية (Imperative).

  • يعني إيه Imperative؟ يعني بنركز على “إزاي” (How) المهمة دي تتعمل. بندي للكمبيوتر أوامر واضحة ورا بعض، خطوة بخطوة، عشان نغير حالة البرنامج (state) ونوصل للنتيجة اللي عايزينها.

الـ Unstructured Programming

ده كان أبسط شكل للكود، يا دوب شوية أوامر ورا بعض وخلاص. وكان بيعتمد على GOTO بشكل كبير، وده سبب مشاكل كتير زي:

  • الكود بيبقى عامل زي الإسباجتي (spaghetti code)، ملخبط وصعب تتابعه.
  • تكرار كتير في الكود.
  • صعوبة وتكلفة تعديل عالية جدًا.
  • مفيش أي تنظيم حقيقي (لا function ولا class).

الـ Structured Programming

دي كانت نقلة كبيرة عشان تحسن طريقة الـ Imperative.

  • بقينا نقسم الكود لأجزاء صغيرة باستخدام Functions عشان يبقى منظم وسهل نرجعله.
  • استخدمنا هياكل تحكم واضحة زي If/Else و Loops بدل الـ GOTO.
  • لغات زي C و Pascal طبقت الفكر ده، وده ساعد في تقليل التكرار وتحسين التنظيم.

بس كان لسه فيه مشاكل:

  • الـ Global Variables: أي جزء في البرنامج يقدر يغيرها، وده بيخلي تتبع الأخطاء كابوس.
  • الـ Stand-alone Functions: كل function لوحدها من غير كيان بيجمعها زي الـ class.
  • التركيز كان لسه على “الخطوات” أكتر من “المفاهيم”.

2. النقلة الكبيرة: الـ Object-Oriented Programming (OOP)

هنا حصلت ثورة في طريقة التفكير. الـ OOP نقلت التركيز من مجرد “الأوامر” للـ Objects.

  • الوحدة الأساسية بقت الـ Class، اللي هو زي تصميم أو قالب بنعمل منه الـ Objects.
  • الـ Class بيجمع البيانات (الخصائص attributes) والسلوك (الأفعال methods) في مكان واحد.

ليه الـ OOP عمل النقلة دي؟ عشان مفاهيمه الأساسية بتحل مشاكل كتير:

  • الـ Encapsulation (التغليف): إخفاء التفاصيل الداخلية للـ class وحماية بياناته، وده بيخلي الصيانة أسهل.
  • الـ Inheritance (الوراثة): بتسمح لـ class إنه ياخد خصائص وسلوك class تاني، وده بيشجع على إعادة الاستخدام (Reusability).
  • الـ Polymorphism (تعدد الأشكال): قدرة الـ objects إنها تتصرف بطرق مختلفة حسب السياق، وده بيدي مرونة (Flexibility) للتصميم.

ملحوظة: رغم إن OOP بينظم الكود بشكل مختلف، إلا إن الكود اللي جوه الـ methods غالبًا بيكون لسه Imperative Programming (يعني خطوات وأوامر).

تاريخ اختراع لغة الـ C# وتطورها

  • زمان، كانت لغة Smalltalk من أوائل اللغات اللي طبقت الـ Object-Oriented Programming (OOP). بس كان صعب على المبرمجين اللي متعودين على لغة زي C Programming إنهم ينقلوا مرة واحدة للغة مختلفة تمامًا زي دي.
  • عشان كده، عملوا لغة تانية اسمها Cpp. هي هياها لغة 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 Type وفيها Wrapper Classes بتحوّلهم لو عايز تعاملهم كـ Objects، بس لو قارناها بـ C++، فالـ Java تعتبر أكتر التزامًا بفلسفة الـ OOP).
  • وبعدين شركة Oracle اشترت شركة Sun.

  • شركة Microsoft كمان كانت عايزة تعمل لغة Pure OOP. فخدوا الأفكار من الـ C والـ C++.
  • عملوا لغة اسمها Cool (اللي هي اختصار لـ C like object oriented language). بس الاسم ده مكنش جذاب أوي في السوق.
  • فكروا يسموها C++++ (أربعة زائد)، بس برضه مكنش اسم لذيذ.
  • ومن هنا طلع اسم [[CSharp Corn Full Course MOC|C#]]. لإن علامة الشباك (#) لو ركزت فيها هتلاحظ إنها شبه أربع علامات ”+” (زائد) فوق بعض وجنب بعض.
  • لغة C# ظهرت كتصميم سنة 2000، لكن أول إصدار رسمي (C# 1.0) طلَع فعليًا في نوفمبر 2002 مع .NET Framework 1.0، والـ Version 2.0 نزل في نوفمبر 2005، وهي بتعتبر Pure OOP (لو قارناها بالـ C++ طبعًا).
    • برضه للتوضيح، هي مش Pure 100% بالمعنى الحرفي الدقيق لكلمة Pure، لإن لسه فيها value types (زي int, bool…) اللي مش Objects بالكامل. لكن بالمقارنة مع C++، هي فعلًا أجبرتك تحط كل الـ code جوه Classes ومافيش حاجة اسمها Functions standalone أو Global variables بره الـ Classes. فلو قصدنا إنها أكتر التزامًا بمبادئ الـ OOP من C++، فده يعتبر كلام سليم إلى حد كبير.
  • نقطة مهمة عن C#: لغة C# (ومعاها كل بيئة الـ .NET) بتعتبر Managed Code. ده معناه إن الكود بتاعك مش بيشتغل مباشرة على الـ Hardware، لأ، ده بيشتغل جوه بيئة خاصة اسمها CLR (Common Language Runtime). الـ CLR دي بتدير حاجات كتير بالنيابة عنك، أهمها الـ Memory Management (إدارة الذاكرة) عن طريق الـ Garbage Collector (GC) (ده عامل زي “جامع القمامة” اللي بينضف الميموري لوحده من أي objects مبقاش ليها لازمة)، وكمان بتوفر طبقة أمان وحماية أعلى للكود بتاعك. ده فرق كبير عن لغات زي C++ اللي بتتعامل فيها مع الميموري بشكل مباشر (ودي بيتقال عليها Unmanaged Code).

3. طريقة تفكير مختلفة: الـ Declarative Programming

على عكس الـ Imperative اللي بيركز على “إزاي”، الـ Declarative بيركز على “إيه” (What) اللي إحنا عايزينه كنتيجة نهائية، من غير ما نحدد الخطوات بالتفصيل.

  • إحنا بنوصف الهدف، واللغة هي اللي بتعرف إزاي توصل للنتيجة.
  • أمثلة مشهورة:
    • الـ SQL: بتقول للداتا بيز “إيه” البيانات اللي أنت عايزها.
    • الـ HTML: بتوصف “إيه” هي مكونات الصفحة (عنوان، فقرة، صورة).
    • الـ CSS: بتوصف “إيه” هو شكل العناصر.
  • علاقتها بـ C#: الـ C# الحديثة فيها أجزاء بتستخدم أسلوب declarative، وأهم مثال هو LINQ.

4. القوة الرياضية: الـ Functional Programming (FP)

ده أسلوب برمجة بيندرج تحت الـ Declarative، وبيشوف البرنامج كأنه مجموعة عمليات رياضية.

المبادئ الأساسية:

  • الـ Pure Functions: دايماً بترجع نفس النتيجة لنفس المدخلات، وملهاش تأثير خارجي (No Side Effects).
  • الـ Immutability: البيانات مش بتتغير. أي تعديل بينتج عنه نسخة جديدة من البيانات.
  • الـ Functions as First-Class Citizens: تقدر تمرر دالة كـ parameter، أو ترجعها من دالة تانية.
  • الـ Avoiding State Changes: بنبعد عن تغيير حالة البرنامج قدر الإمكان.

علاقته بـ C#:

لغة C# دلوقتي بتدعم البرمجة الوظيفية بشكل كبير عن طريق:

  • الـ Lambda Expression: دوال بدون اسم بتسهل كتابة الكود.
  • الـ LINQ: بتكتب استعلامات على البيانات بأسلوب Functional.
  • الـ Pattern Matching: بتسهل التعامل مع هياكل البيانات المختلفة.

مثال توضيحي: سفرة الأكل

  • في Imperative: كل واحد يمد إيده ياخد اللي هو عايزه على طول. النتيجة؟ فوضى.
  • في OOP: الأطباق متغطية (Encapsulation)، ومينفعش تاخد إلا بطريقة معينة (Method). كل حاجة ماشية بنظام.
  • في Functional: كل طبق له طريقة تعامل ثابتة. نفس الطلب (input) = نفس النتيجة (output)، من غير ما حاجة تتغير على السفرة.

الخلاصة والتطور المستمر

رحلة البرمجة تطورت من أسلوب Imperative بسيط، لـ Structured منظم، ثم قفزت قفزة كبيرة مع الـ OOP. بالتوازي، ظهرت أساليب مختلفة زي Declarative و Functional.

اللغات الحديثة زي 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 structure)
 
public class Example // OOP: Class definition
{
    // OOP: Data member (field), encapsulated as private
    private List<int> numbers = new List<int> { 1, 2, 3, 4, 5, 6 };
 
    // OOP: Method containing Imperative code
    public void PrintEvenNumbersImperative()
    {
        System.Console.WriteLine("Even Numbers (Imperative Style):");
        // Imperative: Step-by-step instructions on *how* to find even numbers
        foreach (int number in numbers)
        {
            if (number % 2 == 0)
            {
                System.Console.WriteLine(number);
            }
        }
    }
 
    // A method using a Declarative/Functional approach
    public void PrintEvenNumbersDeclarative()
    {
        System.Console.WriteLine("Even Numbers (Declarative/Functional Style):");
        // Declarative: Describe *what* you want (numbers where n % 2 is 0)
        // Functional: Using a higher-order function (Where) and a lambda
        var evenNumbers = numbers.Where(n => n % 2 == 0);
 
        // Imperative: Still need a loop to print the results
        foreach (int number in evenNumbers)
        {
            System.Console.WriteLine(number);
        }
    }
}