“นี่อาจจะเป็นคำถามที่อยู่ในใจของคนหลายๆคน ตั้งแต่ตอนเรียน โปรแกรมมิ่งแบบ Object Oriented ในมหาลัย”

วันนี้มีน้องคนนึงเข้ามาถามว่า เราจะทำการรับ Message จาก JMS Queue ได้อย่างไร ผมก็ตอบไปว่า ก็ Implement messageListener ของมันสิ ซึ่งตรงจุดๆนี้ ถ้าคนที่ไม่เคยเขียนโปรแกรมที่จะต้องมีการรอรับข้อความ จากระบบภายนอก ก็จะไม่รู้ว่าควรจะทำอะไร แล้วก็จะงงว่าข้อความนั้นมามาได้อย่างไร ซึ่งผมนั้นผ่านการมั่ว ณ จุดๆนั้นมาแล้ว ตั้งแต่ทดลองเขียน XMPP, SNMP protocol ซึ่งล้วนต่างก็ใช้ Listener ในการรับข้อความทั้งสิ้น ซึ่ง Listener ทั้งหลายเหล่านี้ก็ล้วนเป็น Interface ตัวหนึ่งที่เราจะต้องทำการ Implement ซึ่งห้องเรียนในมหาลัยนั้นก็ได้สอนอยุ่แล้ว แต่ท่านอาจารย์สอนเพียงว่า Interface คืออะไร เราก็ได้แต่จำ แล้วก็ลองพิมพ์ๆตาม แล้วก็พบว่า IDE มันฉลาดมาก เติม Method ที่จะต้อง implement ให้เสร็จ โดยที่ไม่ได้รู้เรื่องอะไรเลย ว่ามันเอาไปทำอะไรได้ (อาจจะเป็นเฉพาะตัวผู้เขียน) เวลาผ่านไป 4 ปี เริ่มนึกย้อนในใจว่า แล้วจริงๆมันทำงานอย่างไร ถ้าใครสนใจก็ลองทำตามดูได้เลยนะครับ แต่ผมไม่แน่ใจว่าที่ผมทำลงไปนั้น มันคือสิ่งที่ถูกต้องรึเปล่า ฮ่าฮ่า

โปรแกรมของเราจะประกอบไปด้วยคลาส 3 คลาสด้วยกัน คือ Sender, Receiver และ TestListener และมีอีก 1 interface นั่นก็คือ MessageListener ซึ่งเกิดจากการสร้าง Interface ที่มี Method 2 แบบอยู่ภายในนั่นก็คือ onMessage และ errMessage

MessageListener

interface MessageListener {

 public void onMessage(String message);

  public void errMessage(String message);

}

Receiver

public class Receiver implements MessageListener {

 @Override

public void onMessage(String message) {

System.out.println(“Receiver has received the message \””+message+“\””);

}

@Override

public void errMessage(String message) {

System.out.println(“Receiver has received the error message \””+message+“\””);

} 

}

Sender

public class Sender {

MessageListener msgL;

public void setMessageListener(MessageListener msgL){

this.msgL= msgL;

}

public void sendMessage(String message){

System.out.println(“Sender is sending a message \””+message+“\””);

msgL.onMessage(message);

}

public void sendErrorMessage(String error){

System.out.println(“Sender is sending an error message \””+error+“\””);

msgL.errMessage(error);

}

}

TestListener

public class TestListener {

public static void main(String[] args){ 

Sender sender =new Sender();

Receiver receiver =new Receiver();

sender.setMessageListener(receiver);

sender.sendMessage(“How are you?”);

sender.sendErrorMessage(“Error 404”);

}

}

ผลลัพธ์การทำงาน

Sender is sending a message “How are you?”

Receiver has received the message “How are you?”

Sender is sending an error message “Error 404”

Receiver has received the error message “Error 404”

 คราวนี้เราจะมาลองอธิบายการทำงานกัน ชื่อก็บอกหน้าที่ของแค่ละคลาสอยู่แล้วว่า Sender จะทำการส่งข้อความ โดยจะทำผ่านทางตัวแปร msgL ซึ่งเป็น interface ของเรา ซึ่งจะถูกจะส่งออกไปทาง method onMessage ของ Interface MessageListener 

ตัวแปร msgL นั้นเกิดจาก คลาส Recevier (sender.setMessageListener(receiver)) ที่ทำการ implement interface MessageListener ทำให้เมื่อเราทำการส่ง message ผ่านทาง method onMessage ข้อความที่ส่งออกมานั้นก็จะมาแสดงที่ method onMessage ในคลาส Receiver

บางท่านอาจจะสงสัยว่า แล้วมันต่างกับการสร้าง Class ธรรมดา ที่ไม่มีการ implement interface อย่างไร

ถ้าเราทำในลักษณะนั้น คลาส Sender ของเราก็จะต้องเปลี่ยนตัวแปรจาก MessageListener เป็นชื่อคลาสใดสักคลาสหนึ่ง เช่น Receiver แล้วจึงค่อยทำการส่งข้อความออกทางคลาสนี้โดยตรง ทำให้ถ้าคนอื่น ต้องการจะรับข้อความแบบนี้ในคลาสอื่นๆ ก็จะทำได้ลำบากและซับซ้อนมากยิ่งขึ้น ทำให้โปรแกรมนั้นเข้าใจได้ยาก เหมือนกับโปรแกรมที่ผมเคยทำมาทั้งหมดตลอดในช่วงเวลาที่เรียนมหาวิทยาลัย ที่โค้ดนั้น ไม่มีการ extend หรือ implement คลาส แต่อย่างใด มีแต่การส่ง reference ไปมา ซึ่งทำให้โค้ดค่อนข้างน่าเกลียดมาก

และนี่ก็คือหนึ่งตัวอย่างของการใช้ interface เพื่อมาทำ listener นอกจากนี้ interface ยังสามารถนำไปใช้งานในลักษณะอื่นได้อีก