ใช้ static ได้ไหม
Static
วันหนึ่งระหว่างทำงานรุ่นน้องที่ทำงานถามว่าผมจะทำ Class แล้วใช้ Method เป็น Static ได้ไหม (static คือ keyword ของ java ที่ทำให้สามารถใช้ method หรือ attribute ได้โดยไม่ต้องสร้าง object) ตอนนั้นในสมองก็ผุดคำนึงตอนเรียนวิชา OOAD (Object-oriented analysis and design) ที่ว่า static is evil ขึ้นมาทันที แต่ตอนนั้นก็ต้องฟังก่อนว่าทำไมต้องใช้ จริงๆถามว่าใช้ได้ไหมคำตอบก็คือว่าได้ จริงๆแล้วจะทำอะไรก็ได้หมดแหละจะ SELECT * FROM TABLE แบบไม่ limit จะตั้งชื่อตัวแปรมั่วๆ หรืออะไรก็ตามแต่ แต่คำถามคือมันสมควรทำไหม ในมุมมองของผมการจะใช้ static ต้องดูงานที่จะใช้กับมันว่าทำไมต้องใช้ อย่างแรกเราต้องทำการแยกระหว่าง Class กับ Object ก่อน
Class Vs Object
ถ้าจะเปรียบเทียบ Class เปรียบเสมือนพิมพ์เขียวหรือกรอบที่บอกว่าสิ่งๆหนึ่งต้องมีค่าอะไรบ้างและสามารถทำอะไรได้บ้างเหมือนกับรูปภาพด้านบน Class Dog เป็นตัวบอกว่าหมาตัวนี้ต้องมีค่า Color, Height, Weight และต้องสามารถ Sit, LayDown ได้เป็นต้น แต่ Class ก็ยังคงเป็น Class เป็นแค่กรอบไม่ได้มีตัวตนจริงๆ การที่จะมี Dog จริงๆปรากฏขึ้นมาเราจะต้องทำการสร้าง Object ขึ้นมาภาษาโปรแกรมคือการ Create instance ขึ้นมา Object ที่ถูกสร้างขึ้นมาจะมีค่าเหมือนกับภาพด้านบนที่เมื่อเรา Create instance ของ Class Dog ออกมาเป็น Rayne (อ่านว่าอะไรไม่รู้) จะเห็นว่า Rayne จะมีค่า Attribute ต่างๆขึ้นมาจริงๆและสามารถเรียกใช้ Method ได้
มีไว้ทำไม Static
คราวนี้คำถามว่าแล้วจะมี Static ไปทำไมล่ะ บางครั้งเรามีบางสิ่งที่ไม่จำเป็นต้องมีตัวตนจริงๆแต่ก็สามารถใช้ได้ยกตัวอย่างง่ายๆของ Java คือ Class Math (ได้ยินชื่อแล้วนึกถึงตอนอ่าน Engineering mathematics 1 เลย) ที่มี method และ attribute ที่เกี่ยวกับการคำนวนไว้อยู่แล้วจะเห็นว่า Math ไม่จำเป็นต้องมีตัวตนจริงๆ (ในความหมายของผมคือ Object ) ก็ได้ (ถ้ามีตัวตนเลขวิ่งเข้ามาผมผมคงกลัวน่าดู)
หรือว่าบางที Class อาจจะมีคุณลักษณะบังคับที่ทุก Object ที่ถูกสร้างจาก class นั้นต้องมี และ เราต้องการบอกให้คนที่อ่าน class รู้ว่ามี ตัวอย่างเช่นค่าคงที่บางค่าเช่น เรากำหนดค่า MAX_LEG ของ Dog ให้เท่ากับ 4 เพื่อบอกให้ทั้งจักรวาลรู้ว่า Class Dog อะขามีมากสุดได้ 4 โดยเรียกใช้ผ่าน Class โดยใช้วิธี static แต่วิธีธรรมดาต้องสร้าง Object ขึ้นมาเพื่อถามว่า MAX_LEG มีเท่าไหร่ ลองนึกภาพตลกๆดูเอาละกันว่า อยากจะรู้ว่า Dog มีลักษณะคร่าวๆเป็นยังไงแล้วเราต้องสร้าง Object Dog ขึ้นมา 1 ตัว จากนั้นดูค่าขามากที่สุด พอหมดประโยชน์ก็ทำลาย Dog ทิ้งคงน่าสงสารแย่ (จริงๆคือมันเสียเวลาสร้างและ memory อีกต่างหาก)
ใช้ Static ทุกที่ไปเลย เย้
ตอนผมรู้จัก static ผมก็กะทำอย่างนี้เลยปัญหาคืองานบางงานมันไม่ได้ออกแบบมาให้ใช้ static ลองนึกภาพงานงานนึงนะครับต้องการ print ชื่อคนออกหน้าจอนะครับ ถ้าเขียนแบบ Static จะเป็นแบบนี้
จากภาพจะเห็นว่าแค่จะ Print ถึงกับต้องสร้าง 2 Class มาทำงานแบบนี้ ถามว่าจริงๆผิดไหม ผมว่าไม่ผิดหรอกครับคล้ายๆเราเขียนภาษา C ที่กำหนด struct แล้วเขียน function รับ struct เข้าไปเพื่อ print ออกมา แต่ตอนนี้เราเขียน OOP ที่มันมี method ผูกติดกับ Class แทนที่เราจะมี 2 class เราทำ class เดียวไปเลยสิ
อีกทั้งทุกครั้งที่เราประกาศ static method แล้วเรียกใช้ attribute หรือ method ใน Class ตัวเอง มันจะเป็นการบังคับให้เราต้องให้ attribute หรือ method ที่ถูกเรียกใช้เป็น static ไปด้วย (เหมือนไวรัส) และ ตัว Attribute ที่เป็น public static ที่ไม่ได้ประกาศ final มันก็คือ Global variable ดีๆนี่เอง ใครจะเรียกใช้ ใครจะแก้ก็ได้ตามใจ แก้ตอนไหนก็ไม่รู้ ดังนั้นอันตรายมากที่จะใช้ attribute เป็น public static
สรุป
หลังจากร่ายยาวมานานผมสรุปคร่าวๆได้ประมาณนี้ “เราสามารถใช้ทั้ง static และ ธรรมดาร่วมกันได้แล้วแต่สถาการณ์และความเหมาะสม” และจากนี้จะเป็นวิธีการเลือกใช้ไม่ใช้ static ตอนเขียน code ของตัวผมเองว่าตอนใช้ตอนไหนไม่ใช้
- static
- เราใช้ static กับ Attribute มันเป็นค่าคงหรือค่าที่อยากให้ Class อื่นเห็นและสามารถใช้งานได้ ส่วนใหญ่ผมจะประกาศเป็น public static final type ATTRIBUTE_NAME = X ;
- เราใช้ static กับ Method เมื่อมันเป็นการใช้งานระดับ Class ไม่ใช่ระดับ Object ขอให้นึกถึงตอนเรียกใช้ Math หรือ MAX_LEG เป็นต้น
- เราใช้ static กับ Method เมื่อเรามองว่าเราสร้าง Class นั้นมาเป็น Util หรือ Function Class ประมาณว่าเป็น Class คอยช่วยทำงานบางอย่างซ้ำๆแบบไม่ต้องมีตัวตน Object ตัวอย่างที่เห็นได้ชัดคือ FileUtils, IOUtils