Singleton Pattern คืออะไร?

Singleton Pattern

เป็นรูปแบบการออกแบบซอฟต์แวร์ที่จำกัดจำนวนของ Object ที่ถูกสร้างขึ้นในระบบ ซึ่งจะเป็นประโยชน์เมื่อระบบต้องการจะมี Object นั้นเพียงตัวเดียวเพื่อป้องกันไม่ให้เกิดการทำงานซ้ำซ้อนกันเช่น class สำหรับการเก็บข้อมูล หรือเป็น Model ที่มีการเรียกใช้งานทั้งระบบ

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

เปรียบเสมือนว่าห้อง คือ Application ของเรา และกระดานก็คือ Model นั่นเอง เพราะ Singleton คือ สิ่งของที่มีชิ้นเดียวในโลกถ้าไม่มีก็ทำให้การสร้างขึ้นมา 
แต่ถ้าหากมีแล้วก็ใช้ซ้ำ นั่นเอง

โครงสร้างโค้ดที่เป็นแบบ Singleton (JAVA) หน้าตาก็จะเป็นปะมาณนี้

class diagram

จากโค้ดตัวอย่างด้านบน มีตัวแปรที่มีชื่อว่า instance โดยมี type เป็น Object ที่ชื่อว่า Singleton ซึ่งเป็นตัวแปรแบบ static และมีการเข้าถึงเป็นแบบ private จึงต้องทำการสร้าง method ที่ชื่อว่า getInstance() เพื่อให้ทำการเข้าถึงตัวแปรที่ชื่อว่า instance นั่นเอง

ซึ่งการทำงานของ method getInstance() คือเมื่อมีการเรียกใช้ก็จะเช็คว่าตัวแปร instance นั้นมีค่าเท่ากับ null รึเปล่า ซึ่งครั้งแรกยังไงมันก็ null อะเนาะ และถ้าหากใช่ก็จะทำการกำหนดค่าให้กับตัวแปรโดยจะทำการสร้าง Object ที่ชื่อว่า Singleton ขึ้นมา แต่ถ้าไม่ก็จะทำการ return ตัวแปร instance ออกไป และเนื่องจากว่าตัวแปร instance เป็นแบบ static หมายความว่าจะไม่โดนทำลายทิ้ง พอมีการเรียกใช้ method getInstance() อีกครั้ง ตัวแปร instance ก็จะไม่มีค่าเป็น null ทำให้ไม่ต้องทำการสร้าง Object ขึ้นมาใหม่

และเห็นว่ามีการกำหนด Constructor ของ Class เป็นแบบ private เพื่อป้องกันไม่ให้ทำการสร้าง Object จากข้างนอก ถ้าหากต้องการเข้าถึง Class ต้องทำการเรียกผ่าน method ที่ชื่อว่า getInstance() เท่านั้น โดยการเรียกใช้งานก็จะหน้าตาประมาณนี้

public static void main(String[] args) {
Singleton singleton = Singleton.getInstance();
}

ตัวอย่างการใช้งาน Singleton

ถ้าหากระบบจำเป็นต้องใช้ข้อมูล เช่น ข้อมูลผู้ใช้ตลอดทั้งระบบเพื่อทำการเอามาแสดงผล หรือประมวลผลอะไรสักอย่าง (มีหลายคาลสที่เรียกใช้งานข้อมูลนั้น) ก็สามารถนำเอารูปแบบของ Singleton เข้ามาช่วยแก้ปัญหาได้ ดังนี้

ทำการสร้าง Singleton Class เพื่อเก็บข้อมูลของผู้ใช้เอาไว้

ทำสร้างคลาสใหม่ขึ้นที่นี้คือ Example.java มาเพื่อเรียกใช้งานข้อมูลผู้ใช้ใน UserData.java

สุดท้ายทำการทดสอบโดยทำการกำหนดค่าให้ตัวแปรใน UserData.java และทำการเรียกใช้งานข้อมูลผู้ใช้ผ่านคลาส Example.java ดังนี้

จากตัวอย่างข้างบนก็ดูเหมือนว่าใช้งานได้ไม่มีปัญหาอะไร เพราะเก็บข้อมูลไม่ใหญ่มากไงล่ะ แต่ถ้าหากมีการเก็บข้อมูลจำนวนมากลงใน Singleton ละก็อาจจะเจอปัญหาได้ เพราะอย่าลืมนะว่า Singleton ก็คือตัวแปรที่เป็นแบบ static น่ะ

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

เพิ่มเติม Sigleton ในแบบของ Kotlin

สรุป

การนำเอา Singleton Pattern เข้ามาใช้งานก็เหมือนจะเป็นสิ่งที่ถูกต้อง เพราะไม่จำเป็นต้องมาสร้าง Object ใหม่ทุกครั้งตอนเรียกใช้งาน เช่น พวก Manager หรือ Utility แต่ถ้าหากไม่เข้าใจมันอย่างลึกซึ้งก็อาจจะกลายเป็นสิ่งที่น่ากลัว เนื่องจาก Singleton ก็ถือว่าเป็นตัวแปร static ที่ล่องลอยอยู่ในระบบ ถ้าหากเอามาใช้ในการเก็บข้อมูลที่มีขาดใหญ่ memory ก็ถูกกินไปตามขนาดของข้อมูล ซึ่งถ้าหากไม่มีการจัดการที่ดีก็ทำให้เกิดผลเสียได้ และเรื่องของเขียน Test ของ Model ที่อยู่ในรูปแบบของ Singleton ก็ทำได้ลำบาก เพราะไม่สามารถทำการ Mock model นั้นขึ้นมาได้ สุดท้ายแล้วก็ขึ้นอยู่กับเหตุผลของแต่ละคนว่าจะนำเอา Singleton Pattern เข้ามาใช้งานในรูปแบบไหนแล้วล่ะ