تمرير دالة كمعطى لدالة في الجافا (Callback & Lambda)

إذا كنت من محبي لغة الجافا سكربت (JavaScript)، قد يبدوا لك مثل هذا الكود وهو عبارة عن تعريف دالة (function) وتستقبل دوال كمعطيات (Arguments) أمر طبيعي ومعتاد:

function check_grade(score, pass_callback, fail_callback) {
    let grade = null;
    if (score >= 90) {
        grade = "A";
    } else if (score >= 80 && score <= 89) {
        grade = "B";
    } else if (score >= 70 && score <= 79) {
        grade = "C";
    }  else if (score >= 60 && score <= 69) {
        grade = "D";
    }

    if (grade == null) {
        fail_callback();
    } else {
        pass_callback(grade);
    }
}

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

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

//Test 1
check_grade(81, (grade) => {
    console.log("Congratulation. You got: " + grade);
}, () => {
    console.log("Unfortunately, You failed.");
});

//Test 2
check_grade(55, (grade) => {
    console.log("Yes, you made it. Your grade is " + grade);
}, () => {
    console.log("No, you didn't work hard.");
});

ناتج الكود السابق (Output):

Congratulation. You got: B
No, you didn't work hard.

نلاحظ أنه تم تمرير الدالة كمعطى بطريقة مختصرة بدل الطريقة العادية وهي:

//Test 1
check_grade(81, function(grade) {
    console.log("Congratulation. You got: " + grade);
}, function() {
    console.log("Unfortunately, You failed.");
});

//Test 2
check_grade(55, function(grade) {
    console.log("Yes, you made it. Your grade is " + grade);
}, function() {
    console.log("No, you didn't work hard.");
});

الطريقة المختصرة التي تم اختصار كتابة دالة بها وتمريرها إلى الدالة تسمى (Lambda)، بينما تمرير دالة كمعطى داخل دالة يطلق عليه (callback function).

حسناً، السؤال هنا: هل يمكن تطبيق المثال السابق بلغة الجافا (Java) كما هو في الجافا سكربت؟ الجواب بالتأكيد نعم، ويمكن استخدام كذلك Lambda في الجافا (JDK 1.8).

في البداية، لأستخدام تعبير Lambda، نحتاج إلى تعريف واجهة (Interface) وبهذه الواجهة دالة واحدة فقط بأي اسم، بأي نوع، وباي عدد بارامترات تحتاجها. لتطبيق المثال السابق، سأقوم بعمل هذه الواجهة:

interface Function {
    void apply(String grade);
}

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

    public static void check_grade(int score, Function pass_callback, Function fail_callback) {
        String grade = null;
        if (score >= 90) {
            grade = "A";
        } else if (score >= 80 && score <= 89) {
            grade = "B";
        } else if (score >= 70 && score <= 79) {
            grade = "C";
        } else if (score >= 60 && score <= 69) {
            grade = "D";
        }

        if (grade == null) {
            fail_callback.apply(null);
        } else {
            pass_callback.apply(grade);
        }
    }

لاحظ كيف تم تعريف بارامتر استقبال الدالة وكذلك كيف تم استدعاء الدالة المناسبة من المعطيات داخل الدالة عن طريق الواجهة (Interface) التي قمنا بتعريفها. لنقم الآن بمعرفة كيفية استخدام الدالة التي قمنا بعملها وكيف نكتب تعبير Lambda، كالتالي:

    public static void main(String[] args) {
        //Test 1
        check_grade(81,
                (grade) -> {
                    System.out.println("Congratulation. You got: " + grade);
                },
                (grade) -> {
                    System.out.println("Unfortunately, You failed.");
                }
        );

        //Test 2
        check_grade(55,
                (grade) -> {
                    System.out.println("Yes, you made it. Your grade is " + grade);
                },
                (grade) -> {
                    System.out.println("No, you didn't work hard.");
                }
        );
    }

عند تشغيل البرنامج، سيكون الناتج كالتالي (Output):

Congratulation. You got: B
No, you didn't work hard.

وبهذا تعلمنا كيف نطبق مفهوم Callback Function وكذلك كيفية استخدام Lambda Expressions. في المرفقات تم إرفاق كامل ملف كود المثال الخاص بالجافا والجافا سكربت كذلك.

تم اخذ صورة العرض من callicoder.com

تعليق واحد على “تمرير دالة كمعطى لدالة في الجافا (Callback & Lambda)”

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *