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

[ تمت الإجابة ]كيف OOP يقلل استخدام switch statement

بدأه Adban في 31 أكتوبر 2012 · 6 رد · 1,651 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

كثيرا ما أقرأ في المواقع الأجنبية أن البرمجة على نمط OOP "البرمجة كائنية التوجه" لم تأتي إلا لتقيل استخدام الـswitch statements والـ if-else ..

هل هذا صحيح، وكيف؟ هل من مثال بسيط؟

#2

نعم لكن بشكل غير مباشر :)

فمثلا, القوالب صُممت في الأصل لتفادي عقدة التحميل الزائد إلا أنها يمكنها أيضا تخفيف مشكلة الــ if-else.

فيمكننا كتابة :

#include<iostream>
using namespace std;

template <class T> T display(T X) {
    return X;
}

int main() {
    string str;
    cout << "Enter a number or a character : ";
    cin >> str;
    cout << endl << "You have entered : " << display(str) << endl;
    return 0;
}

بدلا من تعريف عدة دوال و اختبار نوعية المتغير :

if (sizeof (x) == 1)
    displayChar(x);
else if (sizeof (x) == 2)
    displayShort(x);
else if (sizeof (x) == 4)
    displayFloat(x);
else
    displayString(x);

أرجو أن أكون قد أفدتك.

تحياتي.

#3
Adban كتب:

كثيرا ما أقرأ في المواقع الأجنبية أن البرمجة على نمط OOP "البرمجة كائنية التوجه" لم تأتي إلا لتقيل استخدام الـswitch statements والـ if-else ..

هل هذا صحيح، وكيف؟ هل من مثال بسيط؟

ليس هذا صحيح بل ان مفهوم البرمجة كائنية التوجية جاء نتيجة سلبيات اسلوب البرمجة اﻻجرائية فى عمل المشاريع الضخمة والكبيرة.

وبهذا فأن النظرة الى البرنامج قد تغيرت بدﻻ من ان يكون البرنامج كسلسلة من اﻻكواد اصبح كمجموعة من الوحدات المنفصلة عن بعضها البعض ويمكن تجميعها وتطويرها سواء مع بعضها البعض او كمجموعات منفصلة.

post-247365-056865000 1351753540_thumb.p

أنظر اخي الي الصورة السابقة التى توضح الية العمل فى البرمجة اﻻجرائية والبرمجة الكائنية من ناحية دمج البيانات مع الكود ففي OOP كل كائن له بياناتة الخاصة به على العكس فى اﻻجرائية

المرفقات
3Paradigms.png
1

post-15367-027053900%201340345097.gifpost-15367-087183200%201340344597.gif
post-247365-0-10080400-1379403554_thumb.

#4

نعم، في كثير من الأحيان يكون استخدام if..else او switch دلالة على ضعف في تصميم البرنامج.

بسبب ان الفئة التي تستخدمها تكون عرضة دائما للتعديل كلما تم اضافة خيار جديد في جملة if او switch، وهذا يخالف مبدأ مهم في تصميم الكائنات Open/closed principle

فمثلا لو أن لديك مهمة معينة تقوم بادآئها في حالة كانت قيمة متغير ما هي X ، واذا لم يتحقق ذلك تقوم بتنفيذ مهمة أخرى.

class Object
{
private:
    int m_task;
public:
    enum { TaskA = 1, TaskB, TaskC };

    void doAction() {

      if ( m_task == TaskA ) {
	// do action A
      } else if ( m_task = TaskB ) {
	// do action B
      } else if ( m_task == TaskC ) {
	// do action c
      } // else ...

    }
};

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

الحل هو بفصل المهام الى فئات ، واستبدال المتغير الذي يحمل قيمة الحدث بمؤشر يشير الى الفئة التي ستنفذ الحدث، وبالتالي ستفوض مهمة الدالة doAction وقت التشغيل الى أحد المهام.

الحل الصحيح سيكون:

class Task
{
public:
    virtual void doAction() = 0;    
};

class TaskA : public Task {
public:
    void doAction() { // ... }
};

class TaskB : public Task {
public:
    void doAction() { // ... }
};


class TaskC : public Task {
public:
    void doAction() { // ... }
};

class Object
{
private:
    Task* m_task; // created by ctor or factory class.
public:

    void doAction() {
      m_task->doAction();
    }
};

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

امثلة على هذا التصميم وهو نمط برمجي معروف يسمى Strategy Pattern :

- تحديد طريقة ترتيب عناصر بناء على قيمة او اعدادات معينة او بناء على طلب المستخدم.

- تحديد طريقة اطلاق النار لكائن في لعبة.

- تحديد طريقة ال Authentication للدخول على موقع (Active Directory, Form, Web Service)

- تحديد طريقة التأكد من البيانات Validation بناء على نوع القيم.

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

اتمنى ان يكون الشرح واضح ، ويمكنني كتابة درس حول الموضوع للتوضيح اكثر.

وكاجابة على سؤالك:

اقتباس
كثيرا ما أقرأ في المواقع الأجنبية أن البرمجة على نمط OOP "البرمجة كائنية التوجه" لم تأتي إلا لتقيل استخدام الـswitch statements والـ if-else ..

لا ، تقليل استخدام if..else او switch هو احد فوائد استخدام OOP واتباع أنماط التصميم. لكن هناك فوائد اكثر بكثير.

بالتوفيق.

3
#5

أشكرك أخي SudaNix على الإضافة. الا أنها على عكس ماذكرت فلا تخص البرمجة الكائنية :

اقتباس
The essential requirement in the programming language is the ability to store a reference to some code in a data structure and retrieve it. This can be achieved by mechanisms such as the native function pointer, the first-class function, classes or class instances in object-oriented programming languages, or accessing the language implementation's internal storage of code via reflection.

يُمكن تطبيق هذا النمط مع perl و c وكلا اللغتين ليستا كائنية. هذا نفس المثال المكتوب في صفحة ويكيبيديا الا أنه بـc :

#include <stdio.h>

typedef struct _Object {
    int (*executeStrategy)(int a, int b);
} Object;

int ConcreteStrategyAdd(int a, int b);
int ConcreteStrategySubtract(int a, int b);
int ConcreteStrategyMultiply(int a, int b);

void Context(Object *object, int (*executeStrategy)(int a, int b));

int main(int argc, char **argv)
{
    Object object_add;
    Object object_sub;
    Object object_mul;

    Context(&object_add, ConcreteStrategyAdd);
    int add = object_add.executeStrategy(3, 4);

    Context(&object_sub, ConcreteStrategySubtract);
    int sub = object_sub.executeStrategy(3, 4);

    Context(&object_mul, ConcreteStrategyMultiply);
    int mul = object_mul.executeStrategy(3, 4);

    printf("add = %d\n", add);
    printf("sub = %d\n", sub);
    printf("mul = %d\n", mul);

    return 0;
}

void Context(Object *object, int (*executeStrategy)(int a, int b))
{
    object->executeStrategy = executeStrategy;
}

int ConcreteStrategyAdd(int a, int b)
{
    return a + b;
}

int ConcreteStrategySubtract(int a, int b)
{
    return a - b;
}

int ConcreteStrategyMultiply(int a, int b)
{
    return a * b;
}

رأيي من رأي محمد فلا أرى أي علاقة بينهما.

تم تعديل هذه المشاركة بواسطة Mr.B في 1 نوفمبر 2012 في 12:30

3
#6

+!

شكرا جدا للمشاركين، لو هناك مزيد أنتظره.

#7

الـ OOP جاءت لتقسيم العملية البرمجية بصورة يسهل التعديل بالكود وبصور منظمة ولتقسيمها ل classes , objects .. ليس كالبرمجة الاجرائية وال spaciti code

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