**תבנית סינגלטון** (מאנגלית: **Singleton**, בעברית: **יחידן** לפי האקדמיה ללשון העברית) היא תבנית עיצוב (design pattern) בהנדסת תוכנה, אשר נועדה למקרים בהם מעוניינים להגביל את יצירת המופעים של מחלקה מסוימת למופע יחיד, או לעיתים גם למקרים בהם רוצים להגביל את מספר המופעים לכמות קבועה כלשהי. תבנית זו שימושית כאשר נדרש רק מופע אחד על מנת לתאם פעולות במערכת. מתכנתים מסוימים מגדירים את התבנית הזו כתבנית anti-pattern, כלומר, תבנית שנראית מאוד פשוטה וברורה, אבל בפועל היא לא אופטימלית, או שימושית. הגדרה זו נובעת מכך שתבנית זו היא שכיחה מאוד בקרב מפתחים, ולעיתים רבות יוצרת הגבלות שלא לצורך, במצבים בהם אין צורך ממשי במופע יחיד.

מימוש
-----

תרשים UML של מחלקה המממשת את תבנית סינגלטון
מימוש התבנית חייב לעמוד בשני עקרונות: מופע יחיד של המחלקה, וגישה גלובלית. נדרשת האפשרות לגשת לאיבר במחלקה סינגלטון מבלי ליצור אובייקט של המחלקה, וכן מנגנון אשר ישמור את ערכי האיברים של המופע שנוצר. התבנית מושגת באמצעות מחלקה הכוללת פונקציה, אשר בקריאה הראשונה יוצרת מופע חדש, ובקריאות הבאות, מחזירה מצביע לאותו מופע שיצרה קודם. כדי להבטיח שאכן יהיה מופע בודד של המחלקה ולא ניתן יהיה ליצור אותה בצורה אחרת, הגדרת הגישה לפונקציית הבנאי (Constructor) מוגדרת כ-private או protected.

ביישומים מרובי תהליכונים (multi-threaded applications) יש להיזהר במימוש התבנית. אם שני תהליכונים ניגשים לפונקציית הבנייה באותו הזמן, ייתכן מצב בו שניהם ייצרו מופע – מצב אותו אנו מנסים למנוע.

דוגמאות מימוש
-------------

### Java

דרך בטוחה מבחינת תהליכונים (Threads) ב-Java הוצעה על ידי וילאם פו. היא נקראת גם "initialization on demand holder idiom" וממומשת בגישה של "אתחול עצל" (Lazy initialization). בגישה זו, יצירת המופע נדחית עד לרגע האחרון.

```
public class Singleton { 
 // Private constructor suppresses generation of a (public) default constructor
 private Singleton() {}

 /\*\*
 \* SingletonHolder is loaded on the first execution of Singleton.getInstance() 
 \* or the first access to SingletonHolder.INSTANCE, not before.
 \*/
 private static class SingletonHolder { 
 private final static Singleton INSTANCE = new Singleton();
 }
 
 public static Singleton getInstance() {
 return SingletonHolder.INSTANCE;
 }
}

```

דרך המימוש המסורתית האלגנטית והפשוטה מתחשבת בריבוי תהליכים, אך לא מממשת אתחול עצל:

```
public class Singleton {
 private final static Singleton INSTANCE = new Singleton();
 
 // Private constructor suppresses generation of a (public) default constructor
 private Singleton() {}
 
 public static Singleton getInstance() {
 return INSTANCE;
 }
}

```

### #C

```
/// <summary>
/// Thread-safe singleton example without using locks
/// </summary>
public sealed class Singleton
{
 private static readonly Singleton instance = new Singleton();
 
 // Explicit static constructor to tell C# compiler
 // not to mark type as beforefieldinit
 static Singleton()
 {
 }
 
 Singleton()
 {
 }
 
 /// <summary>
 /// The public Instance property to use
 /// </summary>
 public static Singleton Instance
 {
 get { return instance; }
 }
}

```

### ++C

```
class Singleton
{
 private:
 /\* Here will be the instance stored. \*/
 static Singleton\* instance;

 /\* Private constructor to prevent instancing. \*/
 Singleton();

 public:
 /\* Static access method. \*/
 static Singleton\* getInstance();
};

/\* Null, because instance will be initialized on demand. \*/
Singleton\* Singleton::instance = 0;

Singleton\* Singleton::getInstance()
{
 if (instance == 0)
 {
 instance = new Singleton();
 }

 return instance;
}

Singleton::Singleton()
{}

```

### PHP 5

תבנית סינגלטון ב-PHP, גרסה 5:

```
<?php
class Singleton {
  // object instance
  private static $instance;
  
  private function \_\_construct() {}
  
  private function \_\_clone() {}
  
  public static function getInstance() {
    if (self::$instance === null) {
      self::$instance = new self;
    }
    return self::$instance;
  }

  public function doAction() {
    ...
  }
}

//usage
Singleton::getInstance()->doAction();

?>

```

### Objective-C

דרך פשוטה לממש סינגלטון ב-Objective-C:

```
@interface MySingleton : NSObject
{
}

+ (MySingleton \*)sharedSingleton;
@end

@implementation MySingleton

+ (MySingleton \*)sharedSingleton
{
 static MySingleton \*sharedSingleton;
 
 @synchronized(self)
 {
 if (!sharedSingleton)
 sharedSingleton = [[MySingleton alloc] init];
 
 return sharedSingleton;
 }
}

@end

```

אם אין חובה להשתמש בתהליכונים, התיאום (סינכרון) יכול להישאר מחוץ לקוד, ואז הפונקציה `+sharedSingleton` תיראה כך:

```
+ (MySingleton \*)sharedSingleton
{
 static MySingleton \*sharedSingleton;

 if (!sharedSingleton)
 sharedSingleton = [[MySingleton alloc] init];

 return sharedSingleton;
}

```

קישורים חיצוניים
----------------

ויקישיתוף מדיה וקבצים בנושא **סינגלטון** בוויקישיתוף
* דב זילברמן, Design Patterns, הסדרה "תבניות". פרק 3: הסינגלטון.