บางครั้งเราต้องการให้คลาสสามารถสร้างออบเจกต์ได้เพียงออบเจกต์เดียวและแชร์ใช้ออบเจกต์ดังกล่าวทั่วทั้งแอพพลิเคชั่น เราเรียกการเขียนโปรแกรมแบบนี้ว่า Singleton เรามักจะใช้ Singleton กับการควบคุมการเข้าถึงทรัพยากร เช่น การเชื่อมต่อกับฐานข้อมูล หรือ ซ็อกเก็ต ตัวอย่างเช่น คลาสที่เก็บการเชื่อมต่อกับฐานข้อมูลควรจะเขียนเป็น Singleton เพราะการสร้างอ็อบเจ็กต์การเชื่อมกับฐานข้อมูลหลายๆออบเจกต์จะเปลืองหน่วยความจำ หากเป็นการเขียนคลาสแบบ Singleton แอปพลิเคชั่นจะใช้งานเพียงออบเจกต์เดียวในทุกๆส่วนของแอพพลิเคชั่นที่ต้องการเชื่อมต่อกับฐานข้อมูล ซึ่งจะส่งผลให้แอพพลิเคชั่นทำงานได้ดีขึ้นและเร็วขึ้น อีกตัวอย่างหนึ่งของการใช้คลาสแบบ Singleton คือคลาสใช้สร้างออบเจกต์เพื่อเก็บ log สำหรับแอปพลิเคชัน ซึ่งจะเก็บไฟล์ log ที่ใช้เป็นทรัพยากรร่วมกันของทั้งแอพพลิเคชั่น การเขียนโปรแกรมแบบ Singleton เป็นหนึ่งในรูปแบบการเขียนโปรแกรม (code design pattern)
การสร้างคลาสแบบ Singleton ทำได้โดย
- ประกาศตัวแปรแบบ private ที่เป็นออบเจกต์ของคลาสตนเอง
- ประกาศคอนสตรัคเตอร์แบบ private
- ประกาศเมธอดแบบ static ที่เป็น public เพื่อคืนค่าเป็นออบเจกต์เดียวกันกับที่ประกาศในตัวแปรในคลาส
ตัวอย่างด้านล่างเป็นการสร้างคลาสแบบ Singleton
class Singleton {
private static final Singleton instance = new Singleton();
private Singleton() { }
public static Singleton getInstance() {
return instance;
}
}
ตัวอย่างด้านล่างเป็นการประกาศตัวแปรเพื่อเก็บออบเจต์จากคลาส Singleton ซึ่งจะเห็นว่าแต่ละตัวแปรจะเก็บออบเจกต์เดียวกัน
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
Singleton s3 = Singleton.getInstance();
System.out.println(s1 == s2); // true because s1 and s2 refer the same object
System.out.println(s2 == s3); // true because s2 and s3 refer the same object
ตัวอย่างการสร้างออบเจกต์จากคลาส Singleton ด้านบนเป็นการสร้างออบเจกต์เมื่อมีการมีการโหลดคลาสเข้ามาใช้งาน ซึ่งในกรณีที่เป็นคลาส Singleton ที่ต้องโหลดข้อมูลเข้ามาจำนวนมาก เช่น ประกาศคลาสแบบ Singleton เพื่อติดต่อกับฐานข้อมูลอาจจะทำให้การเปิดใช้งานแอพพลิเคชั่นช้าลง เพื่อแก้ปัญหานี้เราสามารถสร้างออบเจกต์เมื่อมีการเรียกใช้งานก็ได้ดังตัวอย่างด้านล่าง ซึ่งออบเจกต์จะถูกสร้างก็ต่อเมื่อมีการเรียกใช้เมธอด getInstance() ถูกเรียกใช้เป็นครั้งแรก
class Singleton {
private static Singleton instance;
private Singleton () { }
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
ใน Java API ก็มีการใช้คลาส Singleton เช่น java.lang.Runtime.getRuntime() หรือ java.awt.Desktop.getDEsktop() หรือ java.lang.System.getSecurityManager