แนะนำภาษา Xtend … กับคำนิยาม Modernized Java

หลังจากที่ไม่ค่อยเรียนรู้อะไรใหม่ ๆ เกี่ยวกับ Java ช่วงนี้ก็ไปเจอะกับอะไรที่น่าสนใจเข้าครับ เป็นภาษาเขียนโปรแกรมที่ชื่อว่า Xtend ซึ่งเป็นโครงการหนึ่งจากมูลนิธิ Eclipse นั่นเอง

นิยามของ Xtend ก็คือ Modernized Java ก็คือการจับเอาภาษา Java ที่อายุกว่า 10 ปีมาแต่งหน้าทำผมเสียใหม่ให้ดูทันสมัย ทัดเทียมกับภาษาเกิดใหม่รุ่นหลาน แต่ยังไม่ทิ้งกลิ่นเดิม ๆ ของ Java

จุดเด่นของ Xtend นั้นก็คือ ตัวโค๊ดที่เขียนด้วย Xtend จะถูกคอมไพล์ไปเป็นโค๊ดในภาษา Java ก่อนที่จะถูกคอมไพล์อีกรอบด้วย Java Compiler ดังนั้นจึงรับประกันได้ว่าโปรแกรมที่เขียนจะเข้ากันได้กับ library หรือโปรแกรมอื่น ๆ ที่เขียนด้วย Java ได้แน่นอน 100 %

ตามธรรมเนียมแล้ว โปรแกรมแรกที่เขียนก็ต้องเป็น Hello World ก่อน Hello World ในภาษา Xtend นั้นมีหน้าตาแบบนี้ครับ

class HelloWorld {
def static void main(String[] args) {
println("Hello World")
}
}

สำหรับชาวชวาอย่างเรา ๆ มันดูคุ้น ๆ ใช่มั้ยครับ โค๊ดข้างบนจะถูกแปลเป็นโค๊ดในภาษา Java ก่อน ซึ่งผลลัพท์มันก็จะเป็นแบบนี้

import org.eclipse.xtext.xbase.lib.InputOutput;

public class HelloWorld {
public static void main(final String[] args) {
InputOutput.println("Hello World");
}
}

ก็แทบจะแม๊พมาตรง ๆ เลย เห็นแล้วก็ อ้าว ไม่เห็นหน้าตื่นเต้นตรงไหนเลยนี่นา ?

ลองเทียบความแตกต่างระหว่างโค๊ดของผม ที่เขียนด้วย Java กับที่เขียนด้วย Xtend ดูนะครับ

package com.playground_soft.chord;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.ListFragment;
import android.view.View;
import android.widget.ListView;

import com.playground_soft.chord.db.DatabaseHelper;
import com.playground_soft.chord.type.Song;
import com.playground_soft.chord.widget.SongListAdapter;

public class _SongListFragment extends ListFragment implements
RefreshThread.OnFinishHandler {

private DatabaseHelper mDbHelper;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setHasOptionsMenu(true);

}

@Override
public void onDestroy() {
super.onDestroy();

mDbHelper.close();
}

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Intent intent = new Intent(getActivity(),
SongDisplayActivity.class);

Song song = (Song)getListAdapter().getItem(position);
intent.setData(Uri.fromFile(song.getFile()));
intent.putExtra("iternal", true);

this.startActivity(intent);
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);

Intent intent = this.getActivity().getIntent();
String artist = intent.getStringExtra("artist");
mDbHelper = new DatabaseHelper(this.getActivity());

this.updateSongList(artist);

}

public void updateSongList(String artist) {

Song mSongs[] = mDbHelper.querySong(artist, true, null, true);
SongListAdapter adapter = new SongListAdapter(getActivity(),
mSongs);

setListAdapter(adapter);
}


@Override
public void onFinished() {
updateSongList(null);

}

}

เทียบกับ เวอร์ชั่น Xtend

package com.playground_soft.chord

import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.support.v4.app.ListFragment
import android.view.View
import android.widget.ListView

import com.playground_soft.chord.db.DatabaseHelper
import com.playground_soft.chord.type.Song
import com.playground_soft.chord.widget.SongListAdapter

public class SongListFragment extends ListFragment implements RefreshThread$OnFinishHandler {

DatabaseHelper mDbHelper

override onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState)
hasOptionsMenu = true
}

override void onDestroy() {
super.onDestroy
mDbHelper.close
}

override onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id)

val song = listAdapter.getItem(position) as Song
val intent = new Intent(activity, typeof(SongDisplayActivity))
intent => [
data = Uri::fromFile(song.file)
putExtra("iternal", true)
]

startActivity(intent)
}

override onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState)

val artist = activity.intent.getStringExtra("artist")
updateSongList(artist)

}

def updateSongList(String artist) {
if (mDbHelper == null)
mDbHelper = new DatabaseHelper(activity)
val mSongs = mDbHelper.querySong(artist, true, null, true)
val adapter = new SongListAdapter(activity, mSongs)

setListAdapter(adapter)
}

override onFinished() {
updateSongList(null)
}
}

จะเห็นว่า โค๊ดดูสะอาดกว่า อ่านง่ายกว่า แต่มีบางจุดที่อาจจะดูงง ๆ ต้องศึกษาสักพักถึงจะเริ่มชินครับ ผมว่าที่จะดูงงที่สุดก็คงเป็นฟีเจอร์ของ Xtend ที่เรียกว่า property

สำหรับ property ใน Xtend นั้นจะต่างกับ C# ตรงที่มันเป็น implicit ก็คือ ถ้ามีการเขียนเมธอด getX() ขึ้นมาในคลาส เราสามารถเรียกใช้เมธอดนี้ในรูปของตัวแปร x ได้เลย แต่จะอ่านได้อย๋างเดียว แต่ถ้ามีเมธอด setX() ที่รับพารามิเตอร์ตัวเดียว จะสามารถเขียนได้ด้วย

วิธีการประกาศตัวแปร ใน java ต้องระบุ type แต่ใน Xtend จะใช้คีย์เวิร์ด var แทน แล้ว type ของตัวแปรนั้นจะถูกกำหนดด้วยค่าที่ใส่เข้าไปในตอนแรก เช่น var index = 0 นั้น ตัวแปรชื่อ index จะมี type เป็น int อะไรทำนองนี้

พูดแค่นี้ก่อนท่าจะดีกว่า … สำหรับใครที่สนใจอยากอ่านก่อนก็เข้าไปศึกษาได้ที่ http://www.eclipse.org/xtend/index.html ครับ

ปล. สังเกตดี ๆ โค๊ดข้างล่างไม่มี semi-colon เลย ในภาษา Xtend semi-colon ปิดท้ายบรรทัดนั้น จะใส่ก็ได้ หรือไม่ใส่ก็ได้ครับ

ใส่ความเห็น

อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *

This site uses Akismet to reduce spam. Learn how your comment data is processed.