ก็เลยคิดว่าจะลองขยาย Idea ของเรื่องนี้ดู
ในหนังสือ Programming in Scala ที่ผมกำลังอ่านอยู่
เขาพูดถึง Mixin ในประเด็น
Thin versus Thick interfaces
Thick interface คือ interface ที่อุดมสมบูรณ์ เพรียบพร้อมไปด้วย method, พร้อมจะให้ developer เด็ด method ที่ต้องการไปเชยชม
ส่วน Thin interface คือ interface ที่มี minimum method
อยากได้อะไรที่เกินกว่าที่จัดหาให้ ก็ออกแรงเขียน code เอาหน่อย
เมื่อเทียบ ruby กับ java แล้ว
java จะออกไปในแนว Thin interface
ส่วน ruby จะออกไปในแนว Think interface
ในหนังสือเขายกตัวอย่างง่ายๆคือ
interface Ordered {
}
ถ้าเป็น Thin interface แล้วหล่ะก็
method ที่ควรจะมี ก็น่าจะมีแค่นี้ก็พอแล้ว
interface Ordered {
/**
* return -1 if this < that
* return 0 if this == that
* return 1 if this > that
*/
public int compare(Ordered that);
}
ถ้า developer อยาก check เงื่อนไข <= ก็ให้ทำแบบนี้เอาเอง
if (this.compare(that) <= 0) {
...
}
แต่ถ้ามองแบบ Think interface ก็ควรจะเป็นแบบนี้
// สมมติว่า java define operator ได้
interface Ordered {
public boolean <= (Ordered that);
public boolean < (Ordered that);
public boolean > (Ordered that);
public boolean >= (Ordered that);
}
Mixin ก็เข้ามามีบทบาทตรงนี้แหล่ะ
กรณี scala เราเขียน Mixin โดยใช้ keywork ว่า Trait ได้ดังนี้
trait Ordered[a] {
// abstract method, class ที่ include mixin นี้ ต้อง implement method นี้
def compare(that: a): Int
def < (that: a): Boolean = (this compare that) < 0
def > (that: a): Boolean = (this compare that) > 0
def <= (that: a): Boolean = (this compare that) <= 0
def >= (that: a): Boolean = (this compare that) >= 0
}
จะเห็นว่า operator 4 ตัวหลังนี้ ถือว่าเป็นของแถม
ตัวอย่างของ Mixin ยอดนิยมของ Ruby ก็คือ Enumerable
class ที่ include Enumerable ไป จะต้อง implement method บังคับ 2 method
ก็คือ
each
กับ <=>
แต่หลังจาก include แล้ว ก็จะมี method ให้ใช้เพิ่มขึ้นมาอีก 22 method.
(น่าจะถือเป็นตัวอย่างที่ดีของ Think interface)