วันพฤหัสบดีที่ 10 กุมภาพันธ์ พ.ศ. 2554

EJB คือ?

EJB - Enterprise Java Bean Architecture



EJB Component.

1. Session Bean
 เป็น Bean ที่ใช้สำหรับการทำงานตาม business logic ต่างๆ หรือ อาจเรียก session bean ว่าเป็น bean สำหรับให้บริการ
session bean แบ่งเป็น 2 ประเภทคือ
1.1. stateless session สำหรับ EJB ประเภทนี้ Application server จะไม่เก็บ State ของ client ไว้ ทำให้การทำงานใช้ทรัพยากรน้อย แต่ละ instance ของ session bean จะให้บริการ client ได้หลาย client
1.2. statefull session สำหรับ EJB ประเภทนี้ Application server จะเก็บ State ของ client ไว้ และไม่มีการใช้ instatnce ร่วมกันของ Client การให้บริการ session bean กับ client จะเป็น 1 ต่อ 1 ซึ่งจะแตกต่างจาก stateless ที่ยอมให้ Client มีการใช้ instance ของ session bean ร่วมกันได้

2. Entity Bean เป็น EJB ที่ใช้สำหรับการทำงานเกี่ยวกับ Data ซึ่งจะทำหน้าที่เป็นตัวแทนของข้อมูลในฐานข้อมูล Entity Bean แบ่งออกเป็น 2 ประเภท คือ
2.1. CMP - Entity Bean (Container-Managed Persistence Entity Bean)
2.2. BMP - Entity Bean (Bean-Managed Persistence Entity Bean)
การสร้าง Stateless Session การ implement Stateless Session Developer จะต้องประกอบไปด้วย
1. remote interface
2. home interface
3. Class สำหรับการ implement Interface
4. ส่วนที่เป็น client (JSP or servlet) เพื่อเรียกใช้งาน session bean

ตัวอย่างการสร้าง Stateless Session Bean
Remote Interface

จะต้องทำการสร้าง method ที่ทำหน้าที่เกี่ยวข้องกับการประมวลผลทาง business process โดย remote interface จะต้อง extends EJBObject. เช่น
HelloObj.java                

package test;
import java.rmi.*;
import javax.ejb.*;
public interface  HelloObj extends EJBObject {
                                String hello() throws RemoteException;
               }
               
Home Interface
Home interface จะทำหน้าที่ในการ create a remote object. ใน class นี้จะมีเพียง methods create() เท่านั้น

HelloHome.java 

package test;
import java.rmi.*;
import javax.ejb.*;

public interface   HelloHome extends EJBHome {
                                 HelloObj create() throws CreateException, RemoteException;
               }
               
Class Implement Interface
จากตัวอย่างการสร้าง interface class ข้างต้นจะต้องทำการ implement method ใน class remote inteface สำหรับตัวอย่างนี้จะต้อง implement method hello() ดังนี้

HelloBean.java 

package test;
import java.rmi.*;
import javax.ejb.*;
import com.caucho.ejb.*;

public class HelloBean extends AbstractSessionBean {
               // no initialization needed
               public void ejbCreate() {
               }
               public String hello() {
                             return "Hello, world";
               }
}
               
จะได้ session bean แบบ stateless แล้วครับ จากนั้นก็มาสร้าง client หรือ ส่วนเรียกใช้งาน session bean ข้างต้น ตัวอย่างนี้จะให้เรียกจาก jsp

Client


สร้าง client ขึ้นมาเพื่อการร้องขอใช้บริการ หรือ เรียกใช้ EJB มีลำดับขั้นตอนการทำงาน คือ

1 . สร้าง home handle สำหรับ remote home.
2. หา home stub โดยอาศัย home handle ที่ได้จากข้อ 1
3. สร้าง remote stub โดยอาศัย home object ที่ได้จากข้อ 2
4. Client เรียกใช้งาน business process หรื method ต่างๆ ใน remote interface ที่เตรียมไว้.

EJB client จะหา home handle ได้จากการช่วยเลือของ JNDI.
ตัวอย่างต่อไปนี้จะแสดงให้เห็นถึงการเรียกใช้งาน EJB โดย JSP ซึ่งจะทำหน้าที่เป็น EJB client และเรียกใช้ method hello ของ EJB ที่ได้เตรียมไว้ด้านบนดังตัวอย่างการ เขียน JSP ได้ดังนี้

hello-ejb.jsp 

<%@ page import="com.caucho.burlap.*, test.*, javax.ejb.*" %>

<%

String url = "http://localhost:8080/ejb/hello";

// create the home handle
HomeHandle homeHandle = new BurlapHomeHandle(url);

// get the home stub
HelloHome home = (HelloHome) homeHandle.getEJBHome();

// create the remote object
HelloObj hello = (HelloObj) home.create();

%>

message: <%= hello.hello() %>



ตัวอย่างการสร้าง Stateless Local Session Remote Interface
การทำงานจะคล้ายกับ EJB ในตัวอย่างข้างต้น แต่จะทำการ extends EJBLocalObject แทน EJBObject.
CounterLocal.java 
package test;
import javax.ejb.*;

public interface CounterLocal extends EJBLocalObject {
int hit();
}

Local Home Interface
จะใช้สำหรับการสร้าง counter instance และจะมีเพียง create() methods เท่านั้น

CounterLocalHome.java 
package test;
import javax.ejb.*;

public interface CounterLocalHome extends EJBLocalHome {
CounterLocal create() throws CreateException;
}

Class สำหรับการ implement 
CounterBean.java 
package test;
import javax.ejb.*;
import com.caucho.ejb.*;

public class CounterBean extends AbstractSessionBean {
int count;

// no initialization needed
public void ejbCreate()
{
}
public int hit()
{
return ++count;
}
}

Client
สร้าง client ขึ้นมาเพื่อการร้องขอ หรือ เรียกใช้ EJB มีลำดับขั้นตอนการทำงาน คือ
1. หา home stub ด้วยการเรียกใช้บริการจาก JNDI.
2. สร้าง local stub โดยอาศัย home object ที่ได้จากข้อ 1.
3. Client เรียกใช้งาน business process จาก Object ที่ได้. 

counter.jsp 
<%@ page import="test.*, javax.ejb.*, javax.naming.*" %>
<%!
CounterLocalHome home;

// Get the home stub once and save it in home
public void _jspInit()
throws ServletException
{
try {
Context env = (Context) new InitialContext().lookup("java:comp/env");

home = (CounterLocalHome) env.lookup("local-ejb/counter");
} catch (NamingException e) {
e.printStackTrace();
}
}
%><%

// create the remote object
CounterLocal counter = home.create();
%>
hit: <%= counter.hit() %><br/>
hit: <%= counter.hit() %>



ตัวอย่าง Entity Bean
 

Home.java 
package test;
import java.rmi.*;

public interface Home extends javax.ejb.EJBHome {
public String hello() throws RemoteException;

public int add(int a, int b) throws RemoteException;
public HomeObj findByPrimaryKey(String a)
throws RemoteException, FinderException;
}

HelloObj.java 
package test;
public interface HelloObj extends javax.ejb.EJBObject {
}

HelloBean.java 
package test;
import javax.ejb.*;

public class HelloBean extends com.caucho.ejb.AbstractEntityBean {
public String ejbHomeHello()
{
return "Hello, world";
}

public int ejbHomeAdd(int a, int b)
{
return a + b;
}

public String ejbFindByPrimaryKey(String key)
throws FinderException
{
throw new FinderException("no children");
}
}

Servlet Implementation

The client in this example is a servlet. As with other EJBs, the client gets the home interface using JNDI. Since it's only necessary to do the JNDI lookup once, the servlet caches the home object as a servlet variable.

package test.entity.home;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

import javax.ejb.*;
import javax.naming.*;

public class HomeServlet                extends GenericServlet {
               Home home;
 public void init() throws ServletException {
               try {
                               Context env = (Context) new InitialContext().lookup("java:comp/env");
                               home = (Home) env.lookup("ejb/home");
                               } catch (Exception e) {
                              throw new ServletException(e);
                     }
               }
 public void service(ServletRequest  req, ServletResponse res) throws IOException, ServletException {
               PrintWriter pw = res.getWriter();
               
               try {
                              pw.println("message: " + home.hello() + "");
                              pw.println("1 + 3 = " + home.add(1, 3) + "");
                              pw.println("7 + 1 = " + home.add(7, 1) + "");
                              } catch (Exception e) {
                              throw new ServletException(e);
                     }
     }
}

credit :  http://www.itmelody.com/tu/ejb.htm

Distributed System คือะไร?


จุดประสงคข์ของ Distributed System คือะไร?

Distributed System คือการสร้าง System ขึ้นมาจาก Component เล็ก ๆ ที่แต่ละ Component สามารถทำงานเสร็จสมบูรณ์ได้ในตัวของมันเอง นำประกอบกันขึ้นเป็นระบบใหญ่ระบบเดียว (Component Based นั่นเอง) จุดประสงค์ของ Distributed System มีอยู่ด้วกัน 3 ข้อด้วยกัน คือ

1. Availability คือ เราต้องการให้ระบบของเราทำงานได้ใกล้เคียง 24 x 7 มากที่สุด Distributed System ทำตรงจุดได้ เนื่องจากว่า ระบบของเราประกอบด้วย Component ต่าง ๆ ทำงานร่วมกัน ถ้ามี Component ใด ๆ ตายไป ส่วนอื่นก็ยังสามารถทำงานต่อไปได้ หรืออาจใช้ความสามารถในการทำ Clustering ของ Application Server เข้าช่วย

2. Scalability คือ ระบบของเรา วันนี้มีคนใช้ 100 คน วันหน้า ถ้าคนใช้เพิ่มเป็น 1000 คน ระบบของเราต้องสามารถรองรับได้ ใน Distributed System ก็สามารถทำได้โดยการเพิ่ม Component เข้าไป หรือทำ Cluster

3. Mainainability เนื่องจากว่า ระบบของเราประกอบขึ้นจาก Component ย่อย ๆ ก็สามารถทำให้เราดูแลจัดการระบบของเราได้ง่าย Application Server หลาย ๆ ตัว ก็สามารถที่จะ Monitor และ Tuning ตัว EJB แต่ละตัวที่รันอยู่ใน Application Server ได้ค่อนข้างละเอียด

นี่ก็เป็น Concept ทั่ว ๆ ไปนะครับ ถ้าเราจะพัฒนา Distributed System ขึ้นมา การใช้ EJB ก็จช่วยลดเวลาในการพัฒนา Distributed System ได้ค่อนข้างเยอะ Developer จะสามารถ Focus ไปที่ Business Logic ได้ ในขณะที่ Application Server จะจัดการ Service ต่าง ๆ ในระดับ Low-Level ให้ เช่น

- Transparency: Client ของ EJB ไม่จำเป็นต้องรู้แน่ชัดว่า Component ที่เราต้องการใช้งานอยู่ที่ไหน Client สามารถอ้างถึง EJB ที่ต้องการใช้ด้วยชื่อ
- Declarative Decurity: สามารถกำหนด Security Constraint ได้โดยการ Config และกำหนดได้ในระดับ Method เลยว่า ใครสามารถใช้ Method ไหน บน EJB ตัวไหนได้บ้าง
- Declarative Transaction: สามารถรกำหนด Behavior ของ EJB ในการทำงานใน Transaction ได้โดยการ Config
- Component Pooling: EJB เป็น Managed Object ซึ่ง Life-Cycle ของมัน ถูกจัดการโดย Container เราไม่จำเป็นต้องสนใจในการสร้าง และ Destroy ตัว EJB, Container สามารถขใช้ EJB จำนวนน้อย ๆ ในการทำงานให้กับ Client จำนวน ๆ มาก ๆ ได้ หรือถ้า Request เข้ามาเยอะ ตัว Container ก็สามารถ Instantiate EJB ขึ้นมาช่วยกันทำงาน ให้เพียงพอกับ Request ที่เข้ามาได้

java เบื้องต้น ครับ


class คือ เสมือนแม่พิมพ์หรือแม่แบบในการสร้าง Objectต่างๆ ที่มีความหลากหลายทั้งนี้เราสามารถหยิบเอา Object ที่สร้างจาก Class หรือ Subclass นี้ไปทำอะไรได้อีกหลายอย่างโดยสั่งงานผ่าน Method ของมัน
Object คือ เหมือนวัตถุชิ้นหนึ่งที่ถูกสร้างขึ้นโดย Classและดึงข้อมูลจาก Class นั้นๆมาใช้ทำให้ Objectมีลักษณะตาม Class ที่สร้างมันขึ้นมา
Method คือ ฟังชันก์ที่อยู่ภายใน Class มีหน้าที่ทำตามคำสั่งที่อยู่ภายใน Method เมื่อถูกเรียกใช้งานแบ่งออกเป็น 3 ประเภทได้แก่
1) Public methodเป็น method ที่ไม่ว่า Class ใดก็เรียกใช้งานได้
2) Private methodเป็น method ที่จะถูกเรียกใช้งานได้จาก method ที่อยู่ในClass เดียวกันเท่านั้น
3) Protected methodเป็น method จะถูกเรียกใช้งานได้จาก method ที่อยู่ในClass และ Subclass เดียวกันเท่านั้น
Service คือ Method ประเภทหนึ่งที่ถูกประกาศมาเป็น public เพื่อให้ Class อื่นเรียกใช้งานได้
Super Class คือ Class หลักที่เรานำมาเพิ่มส่วนต่อขยาย
SubClass คือ Class ที่เรานำมาต่อขยาย Super Class
Static คือ การประกาศล่วงหน้า โดยไม่จำเป็นต้องกระทำใน Method โดยเมื่อเราประกาศตัวแปรแบบ Static แล้ว เราก็สามารถนำตัวแปรนี้ไปใช้ได้ในทุก Method ใน Classนั้นๆ
Finalคือ จบแล้ว เช่น ถ้าเป็นตัวแปรที่ประกาศมาเป็น Final ค่าของตัวแปรนั้นๆจะไม่สามารถเปลี่ยนแปลงได้อีก และ ถ้าเป็น Class ก็จะไม่สามารถสืบทอดClassนั้นๆได้ คือ ไม่สามารถมีSubClass ได้นั่นเอง
Algorithm คือ วิธีการทำงานของตัวโปรแกรมนั้นๆสั้นๆง่ายๆได้ใจความแต่เข้าใจยาก
Attributes คือ คุณสมบัติต่างๆของ Objects เช่นพิกัดของหุ่น สีของหุ่น
Parametersคือ ค่าที่เราส่งไปเวลาที่เราเรียกใช้ Method, Service, Classฯลฯ โดยค่า Parameters อาจมีหลายค่า โดยปกติแล้วจะคั่นด้วยเครื่องหมาย คอมม่า(Comar)
GUI ย่อมาจากคำว่า Graphic User Interface คือส่วนที่เครื่องใช้ติดต่อกับผู้ใช้โดยมีรูปแบบเป็นGraphic
IDE ย่อมาจากคำว่า Integrated Development Enviroment คือเครื่องมือที่ช่วยในการพัฒนาโปรแกรมโดยมีสิ่งอำนวยความสะดวกต่างๆ เช่นคำสั่ง Compile, Runตัวอย่างของ IDE เช่น EditPlus, JCreator, Eclipse แต่ Notepad ไม่นับว่าเป็น IDE เนื่องจากตัว Notepad เอง ไม่มีเครื่องมืออำนวยความสะดวกสำหรับการเขียนโปรแกรมใดๆเลย
ประเภทของ Error มีอะไรบ้าง ?
-Compile Error เป็นประเภทที่ทำให้คนปวดหัวได้มากที่สุด เพราะส่วนมากเจอ Errorประเภทนี้แล้วจะแก้กันไม่ค่อยถูก Compile Error หมายถึง Error ที่เกิดขึ้นจากการCompile เนื่องจากตัว Source Code มีปัญหา
-Run-time Error อันนี้ส่วนมากจะไม่ค่อยเจอ Run-time Error คือ Error ที่เกิดขึ้นระหว่างการ Run ตัว Program แต่ Error ประเภทนี้สามารถดักจับเพื่อใช้คำสั่งอื่นแก้ไขได้ด้วยคำสั่ง Try Catch ตามประเภทของ Exception ดังจะเห็นว่าในPacket ของ BeckerเวลาเกิดRun-time Error กับหุ่นยนต์ตัว Program จะไม่เอ๋อ แต่ตัวหุ่นยนต์จะแตกเป็นชิ้นๆแทน ตามที่มีคำสั่งแก้ไข
-Intent Error เป็นประเภทที่แก้ไขได้ง่ายที่สุด เพราะเกิดจากการที่โปรแกรมออกมาแล้วไม่ได้ดั่งใจ
ประเภทของ Comment มีอะไรบ้าง ?
-One-line Comment ใช้สัญลักษณ์ // ในการเริ่ม โดย Comment ประเภทนี้จะมีผลตั้งแต่สัญลักษณ์ไปจนกว่าจะหมดบรรทัด
-Multi-line Comment ใช้สัญลักษณ์ /* ในการหยุด มีผลตั้งแต่สัญลักษณ์เริ่มจนถึงสัญลักษณ์หยุด
-Document Comment ใช้สัญลักษณ์ /** ในการเริ่ม และ*/ ในการหยุด ขอบเขตเช่นเดียวกับ Multi-line Comment แต่ว่าเวลา Compile แล้วรู้สึกว่าจะถูกใส่เข้าไปในDocumentด้วย
ประเภทของตัวแปร มีอะไรบ้าง ?
int ย่อมากจาก Integer เก็บตัวเลขจำนวนเต็ม,long มีผลเหมือนกันแต่ว่าเก็บค่าสูงสุดต่ำสุดได้มากกว่า Integer
floatเก็บตัวเลขแบบมีทศนิยมได้,double มีทศนิยมได้เหมือนกันแต่ว่าเก็บค่าสูงสุดต่ำสุดได้มากกว่า float
char เก็บตัวอักษรได้ 1 ตัวอักษร
Boolean มีเพียง 2 ค่า คือ true กับ false
String อันนี้ไม่ได้เป็นประเภทของตัวแปร แต่จัดเป็น Class ของตัวแปรเอาไว้เก็บชุดตัวอักษร อักขระต่างๆ
คำสั่งตัดสินใจต่างๆ
ประโยค if
การใช้ if เป็นการเสนอทางเลือกให้กับการประมวลผล แบ่งเป็นสองทางจะเป็นทางไหนก็ขึ้นอยู่กับประโยคเงื่อนไขสำหรับทดสอบว่ามีค่าเป็นจริง หรือเป็นเท็จ
ถ้าประโยคเงื่อนไขสำหรับทดสอบทางเลือกมีค่าเป็นจริง (True) ก็จะทำการประมวลผลในกลุ่มคำสั่งที่ 1 เพื่อให้ได้ผลลัพธ์ออกมา แต่ถ้าเป็นเท็จ (False) ก็จะเลือกทำในกลุ่มคำสั่งที่ 2 ซึ่งทำให้ได้ผลลัพธ์ที่แตกต่างกันออกมา
ตัวอย่าง :if(karel.frontIsClear())
{ karel.move();
}
karel.turnLeft();
นอกจากรูปแบบที่กล่าวมาข้างต้นแล้วก็ยังมีอีกหลายๆรูปแบบของ ifที่ให้ความหมายใกล้เคียงกัน เช่นถ้าต้องการให้ประมวลผล ถ้าประโยคเงื่อนไขเป็นจริง แต่เมื่อประโยคเงื่อนไขเป็นเท็จก็ไม่ต้องทำอะไรเลย
ตัวอย่างif(ประโยคเงื่อนไข)
คำสั่ง ;
นอกจากรูปแบบต่างๆ ข้างต้นแล้วถ้าต้องการให้ประมวลผลในกรณีต่างๆ มากกว่าหนึ่งคำสั่ง ดังนี้
ตัวอย่าง:if(cat.canPickThing())
{ cat.turnLeft();
}
else { cat.turnRight();
}
cat.move();
คือถ้าโรบอทสามารถเก็บของได้แล้วให้เลี้ยวซ้ายถ้าเก็บไม่ได้ให้เลี้ยวขวาเมื่อทำตามคำสั่งนั้นๆแล้วให้เดินไปข้างหน้า...
ประโยค while
การใช้งานประโยค while จะเป็นประเภทของการทำงานในลักษณะวนซ้ำหรือที่เรามักจะได้ยินกันบ่อยๆว่าการวนลูป ซึ่งการทำงานซ้ำในแต่ละรอบนั้นจะประมวลผลกลุ่มคำสั่งเดิมที่อยู่ภายใต้ประโยคwhile ซึ่งรอบของการวนซ้ำจะนานเท่าไรนั้นก็ขึ้นอยู่กับว่าผ่านเงื่อนไขการทดสอบว่าเป็นเท็จหรือไม่ ถ้าเป็นเท็จจริงจึงจะหลุดจากการทำงาน
ตัวอย่าง : while(this.frontIsClear())
{ this.pickThing();
this.move();
}
this.pickThing();
ในบางกรณีอาจจะพบเหตุการณ์ที่เรียกว่า การวนลูปแบบไม่มีที่สิ้นสุดหรือเรียกเป็นภาษาอังกฤษว่าinfinite loop ซึ่งเป็นสิ่งที่ผู้เขียนต้องระมัดระวัง เพราะอาจทำให้เกิดการทำงานที่ผิดพลาดได้
สรุปก็คือ while นี้จะหยุดการประมวลผลโปรแกรมก็ต่อเมื่อประโยคเชิงเปรียบเทียบที่กำหนดไว้มีค่าเป็นเท็จ (ในทางตรงกันข้ามก็คือ ลูป while จะทำการประมวลผลไปเรื่อยๆ ตราบใดที่ประโยคเปรียบเทียบที่ว่านั้นยังคงมีความจริงเป็นจริงอยู่)
การทำงานของ while คือเริ่มต้นจากการประมวลผลประโยคเงื่อนไขว่ามีค่าเป็นจริงหรือเป็นเท็จถ้าเป็นเท็จ กลุ่มคำสั่งต่างๆ ภายในจะไม่ถูกทำการประมวลผลเลยและจบการประมวลผล whileทันที แต่ถ้ามีค่าเป็นจริงกลุ่มคำสั่งภายใน whileนั้นก็จะถูกประมวลผลตามลำดับ จากนั้นประโยคเงื่อนไขก็จะประมวลผลเพื่อตรวจสอบค่าความจริงอีกครั้งและจบการประมวลผลเมื่อค่าความจริงเป็นเท็จ
ประโยค do/while
ในบางครั้งเราก็อาจมีความจำเป็นที่จะนำเอาประโยคเงื่อนไขไปไว้ข้างหลังจากการประมวลผลกลุ่มคำสั่ง แทนที่จะเอามาไว้ด้านบนสุดเหมือนกับที่ใช้ในลูป while ภาษา Java จึงกำหนดรูปแบบการวนซ้ำชนิดนี้ขึ้นมาให้ใช้โดยไม่ได้มีความแตกต่างจากลูป while มากนัก นอกเสียจากการย้ายwhile และเงื่อนไขทดสอบไปอยู่ด้านท้าย
ตัวอย่าง : do
{this.pickThing
}while(this.frontIsClear())
{this.pickThing();
this.move();
}
this.pickThing();
โดยสรุปก็คือ ลำดับของการประมวลผลที่มีการเปลี่ยนแปลงไปจากลูป while นั่นคือ กลุ่มคำสั่งภายใต้ จะถูกประมวลผลก่อนเป็นอันดับแรก ไม่ว่าค่าที่ได้เมื่อนำไปทดสอบกับประโยคเงื่อนไข จะให้ค่าเป็นเท็จตั้งแต่ครั้งแรกเลยก็ตาม หมายความว่ากลุ่มคำสั่งเหล่านั้นจะถูกประมวลอย่างน้อย 1 ครั้ง ผิดกับลูปwhileที่จะไม่ทำอะไรเลยหากว่าค่าที่ได้จากประโยคเงื่อนไขนั้นเป็นเท็จ
ประโยค for
ประโยคควบคุมแบบลูปอีกชนิดที่จะกล่าวถึงก็คือ ลูป for ที่มีเทียบเท่ากับลูป while นั่นคือโปรแกรมไม่ได้มีประสิทธิภาพเพิ่มขึ้นจากการใช้ for มากกว่าการใช้ while แต่อย่างใด เพียงแต่ว่าในการแก้ปัญหาบางปัญหานั้น เมื่อเขียนด้วยลูป forจะทำได้ง่ายกว่าการใช้ลูป while อีกทั้งยังง่ายต่อการทำความเข้าใจของผู้อ่านโปรแกรมด้วย
ตัวอย่าง : public void turnRight
{ for (int turns = 0; turns < 3; turns = turns + 1)
{ this.turnLeft();
}
{

ความหมายของ Abstract Class กับ Interface คือ?


ความหมายของ  Abstract Class กับ Interface คือ?

- Interface ประกอบไปด้วย abstract method เท่านั้น no state, no value, no implementation
- Abstract class เป็นคลาสที่มี abstract method อย่างน้อยหนึ่งเมธอด และส่วนใหญ่จะมี concrete method (เมธอดที่มีส่วน implementation แล้ว) ด้วยก็ได้ นอกจากนั้น abstract class ยังสามารถมี state (พวก attribute หรือ instance variable ต่างๆ) ได้ด้วย
- Concrete class ใดๆที่ได้ inherit จาก abstract class หรือได้ implement interface ใดๆไป ก็ย่อมต้อง implement พวก abstract method เหล่านั้นให้ครบถ้วนสมบูรณ์ จึงจะถือว่า class นั้นเป็น concrete class และสามารถสร้าง instance จาก class นั้นได้
- Class ใดๆก็ตามจะสามารถ inherit จาก abstract class ได้เพียงหนึ่งเท่านั้น แต่จะสามารถ implement interface ได้มากกว่าหนึ่ง (เคยสงสัยมั้ยครับว่าเพราะอะไร นี่แหล่ะครับที่เป็นส่วนหนึ่งที่ทำให้ concept ในการใช้งานระหว่าง interface กับ abstract class แตกต่างกันโดยสิ้นเชิง)
ฟังดูเหมือนว่าไม่แตกต่างกัน ฟังดูเหมือนว่าทั้งสองอันนำมาใช้แทนกันได้ และดูเหมือนว่า Interface มันก็คือ abstract class ที่มีแต่ abstract method และไม่มี instance variable ใดๆเลย ซึ่งก็ใช่ครับ ในภาษา OOP ยุคเก่าๆบางภาษา เช่น C++ นั้น ไม่มี interface ให้ใช้งานหรอกครับ ไม่มีแม้กระทั่ง keyword interface เลยด้วยซ้ำ (ไม่เหมือนกับภาษา Java หรือ VB.net ที่สนับสนุน interface มาตั้งแต่แรกดั้งเดิมในตัวภาษาเลย) แต่โปรแกรมเมอร์ภาษา C++ ก็ยังสามารถใช้ประโยชน์ในเรื่อง interface ได้ ก็ด้วยการใช้ abstract class ที่มีแต่ abstract method นี่ยังไงหล่ะครับ
ทั้งหมดนั้นคือเชิง Technical ครับ ทีนี้มาถึงจุดสำคัญแล้วครับ เรื่องของ concept ที่ทำให้การใช้งาน interface และ abstract method แตกต่างกัน ต้องขอออกตัวไว้ก่อนว่า ผมอธิบายใครไม่ค่อยเป็นเท่าไร ยิ่งเป็นเรื่อง concept เนี่ยก็รู้ๆกันอยู่คับว่ามันเข้าใจยาก ถ้าหากใครอ่านจบแล้ว ทำหน้างงๆ ไม่เข้าใจที่ผมอธิบาย ผมก็ต้องขออภัยไว้ ณ ที่นี้ด้วยครับ
Interface ถ้าแปลกันตรงๆก็อาจจะหมายความว่า "การติดต่อประสาน" ในโลกของความเป็นจริง (และในโลกของ OO) คุณจะพบ interface ได้มากมายในชีวิตประจำวันครับ ยกตัวอย่างเช่น
- คุณกับผม คุยกันรู้เรื่อง เพราะอะไร? เพราะเรามี Interface เรื่องภาษาที่ตรงกัน สมมติว่าเป็น interface IThaiLang ก็แล้วกัน คุณกับผมต่างก็เข้าใจ IThaiLang นี้เหมือนกัน (มองในมุมโปรแกรมมิ่งก็คือ คุณกับผมต่างก็ implement IThaiLang นี้เหมือนกัน) แน่นอนย่อมต้องคุยกันรู้เรื่อง ผมเดินๆไปไปเจอฝรั่งจ๋าคนนึง เผอิญฝรั่งจ๋าคนนั้นพูดไทยไม่ได้ (ไม่ได้ implement IThaiLang นะสิ) แน่นอนผมกับฝรั่งจ๋าคนนั้นก็สื่อสารกันไม่ได้ เพราะไม่เข้าใจ interface ที่ตรงกัน
- รถยนต์ทุกคันต่างก็หยุดจอดที่สี่แยกเมื่อเห็นสัญญาณไฟแดง เพราะอะไร? เพราะรถยนต์คันนั้น (อันที่จริงคือคนขับรถยนต์คนนั้น) เข้าใจว่า สัญญาณไฟสีแดง หมายถึง ให้หยุดรถ นั่นแสดงว่า รถยนต์มีความเข้าใจที่ตรงกันกับป้ายสัญญาณไฟจราจรหรือสามารถติดต่อสื่อสารกันได้ สมมติว่ารถยนต์คันใดก็ตามที่จะเข้าใจสัญญาณไฟจราจรได้จะต้องเข้าใจ interface ITrafficLight (หรือ implement ITrafficLight นั่นเอง) ทีนี้เมื่อรถยนต์ต่างๆวิ่งมาถึงสี่แยกที่มีป้ายสัญญาณไฟจราจรอยู่ ป้ายสัญญาณไฟจราจรเหล่านั้นก็จะส่ง message ไปบอกรถยนต์ต่างๆว่าตอนนี้ไฟจราจรเป็นสีอะไร message ที่ส่งไปนี้ส่งไปโดยใช้ interface ITrafficLight เพราะฉะนั้นรถยนต์คันใดก็ตามที่ implement ITrafficLight นี้ก็จะเข้าใจและหยุดรถเมื่อเห็นสัญญาณไฟสีแดง ในทางกลับกันหากรถยนต์คันไดที่ไม่ได้ implement ITrafficLight นี้ ก็ย่อมจะไม่เข้าใจใน message ที่ส่งมา และแน่นอนย่อมส่งผลให้ขับฝ่าไปแดงไปและถูกหมาต๋าซิวไปในที่สุด
- เมื่อเข้าหน้าหนาว(เหมือนอย่างตอนนี้) อากาศจะหนาว อุณหภูมิจะลดลง ร่างกายคุณย่อมจะรู้สึกว่าหนาว ขนลุก ตัวสั่น เป็นเวลาเดียวกันกับที่ สารปรอทในเทอร์โมมิเตอร์หดตัวลง เพราะอะไร? แน่นอนเพราะคุณและสารปรอทต่างก็เข้าใจว่าอุณหภูมิมันลดลง สมมติว่าออปเจคต์ใดก็ตามที่จะเข้าใจได้ว่าอุณหภูมิลดลงจะต้อง implement ITemperature แสดงว่าทั้งคุณและปรอทในเทอร์โมมิเตอร์ต่างก็ implement ITemperature นี้เหมือนๆกัน และที่คุณและปรอทรู้ว่าอุณหภูมิได้ลดลงแล้วก็เพราะว่าออปเจคต์ Weather ได้ส่ง message มาบอกคุณและปรอทผ่านทาง interface ITemperature นี้เอง ซึ่งคุณและปรอทต่างก็เข้าใจมันได้ดี แต่จะตอบสนองต่อ message นี้อย่างไรก็ขึ้นอยู่กับออปเจคต์มันเอง เช่น คุณอาจตอบสนองโดยการ ตัวสั่น ปากซีด ขนลุก แต่อีกทางหนึ่ง ปรอทตอบสนองต่อ message นี้ด้วยการหดตัว พันธะระหว่างอะตอมแน่นหนาขึ้น ระยะพันธะหนสั้นลง เป็นต้น
จากตัวอย่างทั้งหมดนี้ คุณสังเกตเห็นอะไร
- ออปเจคต์หนึ่งๆอาจถูกสร้างขึ้นมาเพื่อให้สามารถติดต่อสื่อสารกับออปเจคต์ใดๆโดยผ่านทาง interface หนึ่งๆ
(ออปเจคต์คนไทยคนหนึ่งติดต่อสื่อสารกับออปเจคต์คนไทยอีกคนหนึ่งโดยผ่าน interface IThaiLang)
(ออปเจคต์รถยนต์สามารถเข้าใจ message จากป้ายสัญญาณไฟจราจรได้ผ่านทาง ITrafficLight)
จากที่คุณสังเกตเห็น คุณคงจะพอมองออกแล้วว่า interface เหมือนเป็นข้อตกลง (protocol) เพื่อให้ออปเจคต์สามารถติดต่อสื่อสารกันได้ interface บอกถึงลักษณะของช่องทางการสื่อสารว่ามีมาตรฐานเป็นอย่างไร ในเชิงของโปรแกรมมิ่ง interface อาจจะเป็นข้อตกลงที่บอกถึงลักษณะของ message ที่ออปเจคต์จะได้รับหรือส่งไป หรือลึกกว่านั้นก็คือ บอกถึงว่า message ที่จะรับหรือส่งนั้นมี parameter เป็นอย่างไร data type ไหน return ค่าอะไร เป็นต้น
นอกจากนั้นคุณจะสังเกตเห็นว่า ออปเจคต์ที่ implement interface หนึ่งๆ ไม่ได้หมายความถึงความสัมพันธ์แบบ IS-A เฉกเช่นการสืบทอดแบบ inheritance ทั่วๆไป เช่นคุณบอกไม่ได้ว่า "ออปเจคต์คนไทย is a IThaiLang" หรือ "ออปเจคต์รถยนต์ is a ITrafficLight" หรือ "ออปเจคต์ปรอท is a ITemperature" เป็นต้น ต่างจากการสืบทอดแบบ inheritance ทั่วไป เช่นใน คห.7 ซึ่งคุณจะบอกได้โดยสามัญสำนึกว่า "ออปเจคต์ Men is a Person" หรือ "ออปเจคต์ Women is a Person"  และในเมื่อความสัมพันธ์ไม่ได้เป็น IS-A เหมือนอย่าง classical inheritance เพราะฉะนั้นคนส่วนใหญ่มักจะไม่ใช้คำว่า inherit from interface แต่จะใช้ว่า implement interface มากกว่า เมื่อคลาส A เข้าใจใน interface I เราจะเรียกว่า "class A implement interface I" ไม่ใช่ "class A inherit from interface I" และหากคุณสังเกตตั้งแต่ต้น ผมจะใช้คำว่า implement กับ interface เท่านั้น ซึ่งนี่คือเหตุผล
นอกจากนั้นคุณจะพบว่าออปเจคต์ใดๆอาจจะ implement interface ได้มากกว่าหนึ่ง ซึ่งแน่นอนว่ามันควรจะเป็นอย่างนั้น เพราะออปเจคต์อาจจะต้องติดต่อสื่อสารกับออปเจคต์ภายนอกได้มากมายอยู่แล้ว เพราะฉะนั้นการมี interface ไว้ติดต่อสื่อสารกับภายนอกมากกว่าหนึ่งจึงไม่ใช่เรื่องแปลก กลับกันในภาษาที่ไม่นิยม multiple inheritance คุณจะพบว่าคุณไม่สามารถ inherit จาก abstract class ได้มากกว่าหนึ่ง เพราะมันผิดกฏตัวภาษา (ก็ภาษามันไม่นิยม multiple inheritance นี่นา)
ทั้งหมดคือเรื่องของ interface (อันที่จริงผมควรจะอธิบายเรื่อง abstract class ก่อน interface นะ) ทีนี้ในเรื่องของ abstract class เนี่ยผมเข้าใจว่าคุณคงจะพอเข้าใจบ้างอยู่แล้ว (อันที่จริงเริ่มขี้เกียจพิมพ์แล้ว ฮา~)
abstract class ก็คือ class (ไม่ได้กวนนะ) เพราะฉะนั้นสิ่งที่คุณรู้เกี่ยวกับเรื่อง class inheritance ทั่วๆไป ก็ไม่แตกต่างกับการ inheritance จาก abstract class 
คร่าวๆก็คือ abstract class คือคลาสที่คุณยังไม่รู้หรือยังไม่แน่ใจว่างานบางอย่างจะต้อง implement ยังไง ซึ่งคุณก็จะปล่อยให้ method เหล่านั้นเป็น abstract ไป และปล่อยให้คลาสลูกไป implement กันเอาเอง การที่คุณจะ inherit จาก abstract class อะไร คุณควรจะต้องนึกถึงความสัมพันธ์แบบ IS-A ด้วย อย่า inherit มั่วๆ เพราะจะทำให้โครงสร้างมันเสีย ส่วนใหญ่ abstract class มักจะเกิดจากการที่คุณสร้างๆ(หรือออกแบบ)คลาสไปแล้วสังเกตเห็นถึงความสัมพันธ์ระหว่างสองคลาสหรือมากกว่าว่ามีบางอย่างที่เหมือนๆกัน มี method เดียวกัน (แต่อาจจะ implement ไม่เหมือนกัน) คุณก็จะดึงพวกที่เหมือนๆกันเหล่านั้นขึ้นไปเป็น abstract class และปล่อยให้บาง method เป็น abstract ไป แต่อันที่จริงการทำแบบนี้มันไม่ดีแน่นอน สิ่งที่คุณควรทำก็คือ ออกแบบระบบทั้งหมดให้ดีก่อนตั้งแต่ต้น พยายามนึกถึง top-down design คุณคิดว่าในระบบของคุณจะต้องมีคลาสอะไรบ้าง แล้วคลาสอะไรที่พอจะจับเป็นหมวดหมู่เดียวกันได้ ก็สร้างเป็น base class ไป พยายามจัดหมวดหมู่ให้มากที่สุดเท่าที่จะทำได้ base class บางอันของคุณที่ได้อาจจะแค่เป็นต้นแบบให้กับคลาสลูกอื่นๆก็ไม่เป็นไร method ไหนของ base class ที่ no idea to implement ณ จุดนั้นก็ปล่อยเป็น abstract ไป แล้วปล่อยให้เหมือนกับเป็นการบังคับว่าคลาสใดที่จะมาเป็นลูกคลาสนี้จะต้อง make sense กับ method พวกนั้นด้วยเท่านั้นเอง (รู้สึกจะคร่าวๆเกินไป แต่คิดว่าคงเข้าใจดีอยู่แล้วนะครับ)