Return Early Style

คุณเบื่อไหมกับการอ่าน Code

หลังจากเป็น Programmer มาได้ 3 ปีกว่าๆ สิ่งหนึ่งที่เจอแล้วน่าเบื่อสุดๆในชีวิตการทำงานคือ “การอ่าน Code” หลายคนบอกว่าเฮ้ยมันก็เขียนโปรแกรมเหมือนกัน ตอนเรียนอยู่ปี 1 ก็คิดอย่างงั้นนะ แต่พอผ่านชีวิตการเป็น Programmer แล้วมันต่างกันแบบสุดๆ การเขียน Code คือการสร้างอะไรบางอย่างขึ้นมาโดยเราเป็นคนสร้าง เราเข้าใจว่าต้องเอาอะไรไปทำอะไรและจุดมุ่งหมายของการทำงานคืออะไร แต่การอ่าน Code คือการพยายามทำความเข้าใจว่า Programmer คนที่เขียนซึ่งอาจจะเป็นคนอื่นหรือตัวเราเมื่อ 1 ปี หรือ 1 สัปดาห์ที่แล้วกำลังจะทำอะไร เคยมีคนพูดบ่อยๆว่า การเขียน Code ง่ายกว่าการอ่าน Code ตอนนี้เริ่มเข้าใจแล้วว่ามันเป็นยังไง

Programmer แต่ละคนมี Style การเขียน Code ของตัวเอง อันนี้เรื่องจริงๆมาก เพื่อนร่วมงานผมเมื่อมาอ่าน Code ที่ผมเขียนมันสามารถรู้ได้เลยว่าผมเป็นคนเขียน เนื่องจากรูปแบบการประกาศตัวแปร การเว้นวรรค การ Comment ต่างๆ เช่นกัน ถ้าผมไปอ่าน Code ของเพื่อนก็จะรู้ทันทีว่าเพื่อนผมเขียน แต่ประเด็นปัญหามันเกิดจาก Style การเขียนเนี่ยแหละ ต่อจากนี้จะเป็นการเล่าประสบการณ์การเจอ Code แบบนึงตอนทำงานที่เจอแล้วจะร้องไห้ และมาบอกวิธีการแก้ไขกันครับ

อันนี้มันของ If ไหนวะ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public int SomeFunction(bool cond1, string name, int value, AuthInfo perms)
{
int retval = SUCCESS;
if (someCondition)
{
if (name != null && name != "")
{
if (value != 0)
{
if (perms.allow(name)
{
// Do Something
}
else
{
reval = PERM_DENY;
}
}
else
{
retval = BAD_VALUE;
}
}
else
{
retval = BAD_NAME;
}
}
else
{
retval = BAD_COND;
}
return retval;
}

ตอนที่ได้รับ Project หนึ่งจากบริษัทแล้วต้องไปแก้การทำงานของโปรแกรมให้ทำงานตามความต้องการใหม่ของลูกค้า ซึ่งแน่นอนว่ามันต้องเข้าไปอ่าน Code แล้วก็โดนรับน้องด้วย Code แบบนี้เลย คุณอ่านแล้วรู้สึกยังไงครับ สำหรับผม “เหี้ยเอ้ย ไอ else ตรงเนี่ยมันของ if ไหนวะ” แถมอันนี้เป็นแค่ Code สาธิตนะครับ(อันนี้เอามาจาก web ตัวอย่าง) ของจริง Code ตรง if มันยาวมาก ยาวประมาณ 100 - 200 กว่าบรรทัด เอาเป็นว่าคุณสามารถ scroll เมาส์ได้ 4 - 5 ครั้ง พร้อมสบถได้อีกหลายคำกว่าจะจบ if นึง

ถามว่า Code มันทำงานได้ถูกต้องไหม ก็ต้องบอกเลยว่าถูกต้องครับ แต่ถามหน่อยว่าคนมาอ่านเขาจะรู้สึกยังไง ซึ่งคนอ่านอะอาจจะเป็นตัวเองในอีก 1 ปี 10 ปีข้างหน้าก็ได้ แทนที่จะเอาเวลาไปทำอย่างอื่น ต้องมานั่งหาว่านี่มันของ if ไหนวะ

ถ้าอ่าน Code ดีๆแล้วมันไม่ได้ทำอะไรเลยครับ มันแค่ Validate ข้อมูลที่ส่งเข้ามาตามเงื่อนไขต่างๆแล้ว Return กลับออกไป ซึ่งถ้าเอามาเขียนใหม่ใน Style ที่เรียกว่า “Return Early” จะได้ออกมาเป็นแบบนี้

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public int SomeFunction(bool cond1, string name, int value, AuthInfo perms)
{
if (!someCondition)
return BAD_COND;

if (name == null || name == "")
return BAD_NAME;

if (value == 0)
return BAD_VALUE;

if (!perms.allow(name))
return PERM_DENY;

// Do something
return SUCCESS;
}

ทุกอย่างทำงานเหมือนกันหมดแต่อ่านง่ายสบายตากว่า เข้าใจง่ายกว่า แค่มันมี return เพิ่มขึ้นซึ่งในบางที่บอกว่ามันไม่ดีเพราะจะทำให้ตกหล่นเวลาไล่ Code เพราะคนเขียนจะสนใจเฉพาะกรณีส่วนที่ต้องแก้หรือทำการเพิ่ม if อีก if นึงไว้ก่อนแล้วให้ return ทำให้ไม่สนใจ Logic โดยรวม แต่ถ้าถามผมผมชอบ Style return มากกว่าเพราะมันทำให้ Code อ่านง่ายดูเป็นกรณีกรณีไป

สรุปโดยใช้ความเห็นส่วนตัว

โดยใช้ความคิดเห็นส่วนตัวแล้วผมแนะนำให้ใช้ Return Early กับ Code ที่มีการเช็คเงื่อนไขก่อนจะทำส่วนหลัก เช่น validate data ก่อนทำการแก้ไขข้อมูล หรือ ทำการ Check state ของสินค้าก่อนจะทำการอนุมัติให้ทำขั้นตอนต่อไปได้ เพราะทำให้เข้าใจเงื่อนไขต่างๆได้ง่ายในระดับสายตาเดียว ซึ่งดีกว่าการไล่ดู if แต่ละ if ที่ห่างกันโคตรๆแล้วก็ลืมต้องเลื่อนไปเลื่อนมา 10 กว่ารอบกว่าจะเข้าใจเงื่อนไขทั้งหมด แต่ขอให้พึงระลึกเสมอว่าถ้าคุณใช้วิธีการเขียนแบบ Return Early คุณต้องอ่าน Code ทุกเงื่อนไขและทำความเข้าใจที่มาของแต่ละเงื่อนไข และอย่าสร้างเงื่อนไขที่ไม่จำเป็นขึ้นมาครับ

หนังสือแนะนำให้อ่าน

มีหนังสือเล่มนึงที่ผมแนะนำให้อ่านคือ The Art of Readable Code เล่มนี้อ่านง่าย สนุก มีรูปประกอบที่ฮาช่วยให้เข้าใจเพิ่มขึ้นอีกด้วย ตัวอย่างภาพ

"สิ่งที่ผมเขียนขึ้นเป็นเพียงความรู้และความเข้าใจของบุคคลเพียงบุคคลเดียว ดังนั้นอย่าเพิ่งเชื่อในสิ่งที่ผมเขียนและอธิบาย ลองทำความเข้าใจว่ามันเป็นจริงอย่างนั้นไหมและลองหาแหล่งอ้างอิงอื่นๆว่าเขามีแนวคิดอย่างไร เรื่องการ Design และวิธีการใช้งานไม่มีถูกไม่มีผิดมีแต่เหมาะสมกับงานนั้นไหม"

ref :
https://softwareengineering.stackexchange.com/questions/18454/should-i-return-from-a-function-early-or-use-an-if-statement