วันเสาร์ที่ 9 พฤษภาคม พ.ศ. 2558

Mixin in Scala

วันนี้เราจะมาดูเรื่องของ Mixin ใน ภาษา Scala กัน ก่อนอื่นผมอยากจะให้ดูนิยามของคำว่า Mixin ก่อนเผื่อว่าใครยังไม่คุ้นเคยกับคำนี้ นิยามต่อไปนี้ผมเอามาจาก Wiki  (en.wikipedia.org/wiki/Mixin)
  1. In object-oriented programming languages, a mixin is a class that contains a combination of methods from other classes. How such a combination is done depends on the language. If a combination contains all methods of combined classes, it is equivalent to multiple inheritance.
ถ้าจะแปลเป็นภาษาไทยก้อน่าจะได้ความว่า mixin คือ class ที่ประกอบด้วยเมทธอดจาก class อื่นหลาย class แต่ไม่จำเป็นตัองมีทั้งหมดเหมือนกับ inheritance   โดยที่มีแค่บางเมทธอดเท่านั้น  อย่างไรก้อตามถ้ามีทุกเมทธอดที่มาจากทุก class มันก้อเหมือนกับ multiple inheritance เดี่ยวเราค่อยมาดูตัวอย่างกัน

ก่อนอื่นต้องบอกว่าใน ภาษา Scala เราสามารถ Mixin class (mix methods and properties into some class) โดยการใช้ Trait และ keyword with

เรามาดูตัวอย่างกัน คราวนี้ FileDataSource ไม่ได้ extends DataSource อีกต่อไป สังเกตุว่า DataSource มีเมทธอด otherMethod แต่ FileDataSource ไม่มีและไม่เป็นไรเนื่องจาก FileDataSource ไม่ได้ extends DataSource

trait DataSource {
  def otherMethod()
  def read() : Boolean
  def getString() : String
  
  def printAll() {
    while(this.read()) {
      println(getString())
    }
  }
}

class FileDataSource  {
   val max = 5
   var count : Int = 0
   
   def read() :Boolean = {
     count = count + 1
     return count < max
   }
   def getString():String = { 
       return "count=> " + count
  }
}

คราวนี้เรามี Trait เพิ่มอีกหนึ่ง และมีเมทธอด otherMethod และ write 

trait Logger {
  def otherMethod() {}
  def write(message: String) {
    println(message)
  }
}

เรามาดูวิธี Mixin กัน ผมอยากจะ Mix in printAll จาก DataSource  และ write จาก Logger ไปให้ FileDataSource ได้ใช้โดยที่ไม่ต้องการ inheritance  เราทำได้ดังนี้

object Hello {
  def main(args: Array[String]) {
    var a =new FileDataSource() with DataSource with Logger
    a.printAll()
    a.write("done")
  }
}

จะเห็นได้ว่าผมสร้าง instance ของ FileDataSource (ที่ไม่ได้ประกาศ printAll  และ write) และ mix in DataSource และ Logger ให้ ด้วย keyword with หลังจากที่สร้าง instance a แล้ว ผมเรียกเมทธอด  printAll จาก DataSource และ write จาก  Logger  ผลลัพธ์ที่พิมพ์ออกมาคือ

count=> 1
count=> 2
count=> 3
count=> 4
done

ไม่มีความคิดเห็น: