อันนี้เป็นวิธีที่ผมใช้ นอกเหนือจากพวก style guide ที่ให้มาตามภาษาต่าง ๆ เอามาแชร์ให้ฟังกันเผื่อว่าน่าสนใจนะครับ

ชื่อ Method ควรสื่อถึงการกระทำ (action)

นึกภาพก่อนนะครับว่า เวลาเขียนโค๊ด method คือการสั่งให้วัตถุ (object) ทำอะไรสักอย่าง ดังนั้น ชื่อ method ควรจะสื่อถึงการกระทำอย่างชัดเจน และไม่ยาวเยิ่นเย้อ

โดยทั่ว ๆ ไปเราก็จะเขียนชื่อ method เป็น verb + object ตามไวยากรณ์ภาษาอังกฤษ อย่างเช่น

  • println()
  • getCount()
  • calculate()

ตัว verb อาจจะเป็นเอกพจน์ หรือพหูพจน์ก็ได้ แต่ตาม style guide ส่วนใหญ่มักจะระบุให้เขียนเป็นเอกพจน์ ทั้ง ๆ ที่มันมักใช้กับตัวแปรที่เป็นเอกพจน์ก็ตาม (เข้าใจว่าเป็นการประหยัดหน่วยความจำครับ ได้ 1byte :)) อันนี้เราก็เขียนตามไกด์เลย ไม่ต้องกังวลอะไร

get กับ set ใช้กับ getter และ setter ตามลำดับ

อันนี้ไม่ได้เกี่ยวกับการ์ตูนหุ่นยนต์ หรือวอลเล่ย์บอลแต่อย่างใด getter กับ setter เป็น method ที่ทำหน้าที่เป็นตัวดึงข้อมูลออกจากวัตถุ กับ กำหนดข้อมูลเข้าไปในวัตถุ (ตามลำดับ) อย่างเช่น ...

class Student {
  public Student(String name) { setName(name); }
  private String name;
  public String getName(){ return name; }
  public String setName(String name) { this.name = name;}
}

ตามความหมายแล้ว getter เป็นการดึงข้อมูลออกมาจากวัตถุ ก็คือสิ่งที่ตัววัตถุนั้นเป็นเจ้าของอยู่ แต่บางครั้งเราจะเจอ method แบบนี้

class StudentUtil {
  public static Student getNewStudent(String name) { 
    return new Student(name); 
  }
}

ซึ่งตัว class มีความสัมพันธ์กับตัวผลลัพท์น้อยมาก ตัวผลลัพท์เองไม่ได้มีใครเป็นเจ้าของ (สังเกตว่าเป็นวัตถุใหม่) ดังนั้นชื่อ getNewStudent() อาจจะดูไม่สื่อความหมายสักเท่าไหร่ method นี้จะดีกว่าถ้าใช้ชื่อแบบ createNewStudent() เป็นต้น

เขียนชื่อ method ตาม design pattern

design pattern เป็นรูปแบบการออกแบบคลาสที่เป็นทำกันบ่อย ๆ เป็นรูปแบบซ้ำ ๆ ซึ่งมีโปรแกรมเมอร์ 4 ท่านสังเกตและนำเอารูปแบบที่ซ้ำ ๆ กันมารวบรวมออกมาเป็นหนังสือที่ชื่อว่า Design Patterns โดยกำกับชื่อเอาไว้ว่ารูปแบบไหนมีชื่อเป็นอย่างไร

ตัวอย่างข้างบนนั้น ตัว method createNewStudent() เป็นแพทเทิร์นที่ชื่อว่า Factory Method ซึ่งเป็น method ที่ทำหน้าที่สร้างวัตถุใหม่แล้วคืนกลับไปให้ผู้เรียก method ในแพทเทิร์นนี้เรามักจะใช้ชื่อที่ขึ้นต้นว่า "create" ซึ่งมันก็สื่อความหมายในตัวของมันได้ดี

ผมจะยกอีกสักตัวอย่าง คือ Builder ซึ่งเป็นคลาสที่ทำหน้าที่สร้างวัตถุใหม่เช่นกัน แต่ว่าวิธีการสร้างจะซับซ้อนกว่า อย่างเช่น class Uri.Builder ใน Android เนี่ยจะใช้ในการสร้าง uri ซึ่งเจ้าคลาสนี้จะมี method จำนวนหนึ่งในการตั้งค่าพารามิเตอร์ของวัตถุที่มันกำลังสร้างอยู่ และมี method ชื่อ build() ในการเอา parameter ทั้งหมดที่มันรับมาก่อนหน้านี้ไปสร้างเป็นวัตถุใหม่ (ต่างกับ create() ที่มักจะใช้ parameter ของ method ในการสร้างวัตถุ)

ผมยกตัวอย่างการใช้คลาสนี้จาก StackOverflow นะครับ แต่จะดัดแปลงให้ดูเข้าใจง่ายก่อน (วิธีใช้ที่เหมาะสมจริง ๆ อยู่ในลิงค์ ดูเองนะครับ)

Uri.Builder builder = new Uri.Builder();
builder.scheme("https");
builder.authority("www.myawesomesite.com");
builder.appendPath("turtles");
builder.appendPath("types");
builder.appendQueryParameter("type", "1");
builder.appendQueryParameter("sort", "relevance");
builder.fragment("section-name");
Uri uri = builder.build();

โค๊ดชุดนี้สร้าง uri ว่า https://www.myawesomesite.com/turtles/types?type=1&sort=relevance#section-name ครับ อ้อ ... URL เป็น URI ประเภทนึงครับ

method ที่ใช้รับ event (event handler) นำหน้าว่า on

อันนี้แหกกฎข้อบนนิดหน่อย ตรงที่ onXXX ไม่ได้เป็นรูปของ action ครับ (on เป็น ...preposition เป็นคำนำหน้าจังหวะเวลา ประมาณว่า on sunday, on monday หรืออะไรก็ว่าไป ;-)) ตรงนี้เป็นข้อยกเว้น เป็นรูปแบบที่ใช้กันโดยทั่วไปครับ ไปแหกกฎเขาเดี๋ยวชาวบ้านจะอ่านโค๊ดเราไม่รู้เรื่องน่ะ

ถ้าเกิดว่าดีไซน์ของคลาสมีการกระทำบางอย่างที่ บางส่วนถูกกำหนดตายตัว และบางส่วนสามารถแก้ไขได้ในคลาสย่อย ให้แยกเป็นสอง method โดย method ที่แก้ไขได้ให้ขึ้นต้นด้วยคำว่า do

สมมติว่า เรามีคลาสที่เก็บข้อมูลแล้วมีการตรวจสอบข้อมูล (validation) แล้วเราดันจำเป็นต้องเคลียร์เจ้า errorList ทุกครั้งที่มีการ validate เราก็สามารถเขียนแบบ

class abstract Data {
  private List<Error> errorList;
  public final void validate() {
    errorList.clear();
    doValidate(errorList);
  }
  public abstract void doValidate(List<Error> errorList);
}

class abstract IntegerData {
  private int value;
  private static final int MAX_VALUE = 100000;
  public void doValidate(List<Error> errorList) {
    if(value > MAX_VALUE ) 
      errorList.add(new MoreThanMaximumWarning(value, MAX_VALUE));
    else if(value < 0) {
      errorList.add(new LessThanZeroError(value);
      return;
    }
  }
}

เจ้า doValidate เนี่ยเป็น method ที่ทำงานในส่วนที่ถูกเปลี่ยนแปลงได้จากคลาสย่อย ที่เราใส่คำว่า do ข้างหน้าเพื่อเป็นการบอกว่าจริง ๆ แล้วมันจะถูกเรียกจาก method ไหน (ซึ่งตามหลักแล้วก็ไม่ควรมีมากกว่า 1 method ที่เรียกครับ) เหมือนกับเป็นตัวย้ำนั่นแหละ