หลังจากที่ได้เขียนบทความแนะนำเรื่อง Callback บน JavaScript และ Callback บน VB.NET ไป เมื่อไม่นานมานี้ (แค่ปีกว่า ๆ เอง) คราวนี้ของคราวของ Java บ้าง (ใครยังไม่เข้าใจว่า Callback คืออะไร อ่านตอนที่แล้วก่อนนะครับ)
เนื่องจาก Java นั้น ไม่มี Delegate เหมือนของ VB.NET และไม่สามารถส่งชื่อ Function เข้าไปได้เหมือนของ JavaScript ถ้ายังงั้นแล้ว จะใช้วิธีไหนดี!?
คำตอบก็คือ ใช้ความสามารถของ Interface นั่นเอง… ด้วยความที่ภาษา Java เป็นภาษา OOP ค่อนข้างจัด ไม่ได้ออกแบบให้ทำอะไรง่ายไปหมด (จนไม่รู้เรื่อง) เหมือนอย่าง VB.NET แต่ทำให้เราได้เรียนรู้วิธีการแปลก ๆ ใหม่ ๆ
List of contents
สำหรับบทความนี้ ขอยก Code จากของ JavaScript มาเขียนเปรียบเทียบให้ดูนะครับ
1 2 3 4 5 6 7 8 9 10 11 |
function fnWorkSecond(data_back) { document.writeln("Work Second<br>"); document.writeln(data_back); } function fnWorkFirst(callback) { document.writeln("Work First<br>"); callback("send data back"); } fnWorkFirst(fnWorkSecond); |
1 2 3 |
Work First Work Second send data back |
Design interface
ตัวอย่างจาก JavaScript สังเกตว่า fnWorkSecond นั้น ถูกส่งเป็น Parameter ให้กับ fnWorkFirst ซึ่งในภาษา Java ไม่สามารถทำแบบนี้ได้ เราจึงจำเป็นต้องสร้างเป็น Interface ที่มี Method ตามโครงสร้างแบบเดียวกับ fnWorkSecond ขึ้นมา ดังนี้
1 2 3 |
private interface IWorkSecondCallback { public void fnWorkSecond(String data_back); } |
จาก Code ด้านบน เป็นการสร้าง Interface โดยกำหนดให้มี 1 Method ที่ล้อตาม fnWorkSecond นั่นเอง
Implement interface
เมื่อสร้าง Interface ขึ้นมาแล้ว ถึงเวลาทำการ Implement interface ขึ้นมาเป็น Class โดยให้ Code การทำงานของ fnWorkSecond นั้น อยู่ภายใน Method ดังนี้
1 2 3 4 5 6 7 |
private class WorkSecond implements IWorkSecondCallback { @Override public void fnWorkSecond(String data_back) { System.out.println("Work Second"); System.out.println(data_back); } } |
เราก็จะได้ Class WorkSecond ซึ่งมี Method fnWorkSecond() ไว้ทำงานเหมือนกับ Function fnWorkSecond ของ JavaScript แล้ว
Interface parameter type
ทีนี้ถึงคราว fnWorkFirst กันบ้าง เพื่อให้สามารถทำการ Callback ได้ สำหรับ Java เราก็ใช้ Interface กำหนดเป็นชนิดของ Parameter และใช้ Parameter นั้น เรียกใช้งาน Method fnWorkSecond() ให้ ดังนี้
1 2 3 4 |
private void fnWorkFirst(IWorkSecondCallback callback) { System.out.println("Work First"); callback.fnWorkSecond("send data back"); } |
เวลาใช้งานก็…
1 |
fnWorkFirst(new WorkSecond()); |
รวม ๆ แล้วก็เป็น
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
private interface IWorkSecondCallback { public void fnWorkSecond(String data_back); } private class WorkSecond implements IWorkSecondCallback { @Override public void fnWorkSecond(String data_back) { System.out.println("Work Second"); System.out.println(data_back); } } private void fnWorkFirst(IWorkSecondCallback callback) { System.out.println("Work First"); callback.fnWorkSecond("send data back"); } fnWorkFirst(new WorkSecond()); |
ลองรันดู ก็จะได้ผลลัพธ์แบบเดียวกับ JavaScript เป๊ะ ๆ
Implement anonymous class
พิเศษหน่อย สำหรับภาษา Java เราสามารถ Implement interface แบบใช้งานในจุดนั้นเลย (Anonymous Class) โดยไม่ต้องไป Implement เป็น Class แบบข้างบน ซึ่งก็จะออกมาคล้าย ๆ ของ JavaScript ในบทความก่อน ที่เขียน Code ออกมาเป็นแบบนี้
1 2 3 4 5 6 7 8 9 |
function fnWorkFirst(callback) { document.writeln("Work First<br>"); callback("send data back"); } fnWorkFirst(function (data_back) { document.writeln("Work Second<br>"); document.writeln(data_back); }); |
สำหรับภาษา Java เขียนได้เป็นแบบนี้
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
private interface IWorkSecondCallback { public void fnWorkSecond(String data_back); } private void fnWorkFirst(IWorkSecondCallback callback) { System.out.println("Work First"); callback.fnWorkSecond("send data back"); } fnWorkFirst(new IWorkSecondCallback() { @Override public void fnWorkSecond(String data_back) { System.out.println("Work Second"); System.out.println(data_back); } }); |
จบแล้ว… ไม่ยากใช้ไม๊ครับ สำหรับ Callback บนภาษา Java
การเขียนแนว ๆ นี้ มีให้เห็น มีให้ใช้ หรือต้องใช้ ก็เยอะอยู่นะ จากที่ผมจับ Java for Android มาราว 2 ปี ก็ใช้ Callback ค่อนข้างเยอะ ไม่ว่าจะเป็นด้านของการ Design ให้ออกมาในด้านของการสร้าง Callback เช่นการโยนงานให้ภายนอก Function ทำ หรือด้านของการใช้งานในแบบ Callback เช่นพวกการดักเหตุการณ์ต่าง ๆ
ลองทำความเข้าใจ แล้วลองฝึกดูนะครับ มันได้ใช้เยอะจริง ๆ นะ โดยเฉพาะ Java for Android นี่ มี Callback ตั้งแต่เริ่มต้นเลยล่ะ ไม่เชื่อลองอ่านบทความตอน Activity Lifecycle พื้นฐาน Android ที่ Developer ควรรู้ ดูก็ได้