Kody źródłowe/Singleton (wzorzec projektowy)
Java
edytujRozwiązanie 1 (jest Thread Safe) (Eager)
edytujpublic final class Singleton {
private final static Singleton ourInstance = new Singleton();
public static Singleton getInstance() {
return ourInstance;
}
//żeby uniknąć automatycznego tworzenia domyślnego, publicznego, bezargumentowego konstruktora
private Singleton() {
}
}
Rozwiązanie 2 (tylko Java 5 i nowsza) (To rozwiązanie jest Thread Safe)
edytujpublic final class Singleton {
// należy zwrócić uwagę na użycie słowa kluczowego volatile
private static volatile Singleton instance = null;
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
// żeby uniknąć automatycznego tworzenia domyślnego, publicznego, bezargumentowego konstruktora
private Singleton() {
}
}
Rozwiązanie 3 (Rozwiązanie nie jest Thread Safe) (lazy)
edytujpublic class Singleton {
//żeby uniknąć automatycznego tworzenia domyślnego, publicznego, bezargumentowego konstruktora
private Singleton() {}
private final static class SingletonHolder {
private final static Singleton instance = new Singleton();
}
public final static Singleton getInstance() {
return SingletonHolder.instance;
}
}
Rozwiązanie 4 (tylko Java 5 i nowsza)
edytujpublic enum Singleton {
//synchronizacja oraz unikatowość zapewniona przez maszynę wirtualną Javy
INSTANCE
}
JavaScript
edytujRozwiązanie 1
edytuj//"new" uniemożliwia tworzenie kolejnych instancji
var singleton = new function() {
this.foo = 0;
this.bar = function() {
alert(this.foo);
};
};
singleton.foo = 5;
singleton.bar(); //wypisze 5
Rozwiązanie 2 (JSON)
edytuj//"new" nie utworzy obiektu na podstawie tablicy..
var singleton = {
foo : 0,
bar : function() {
alert(singleton.foo);
}
}
singleton.foo = 5;
singleton.bar(); //wypisze 5
PHP 5
edytuj<?php
class Singleton
{
private static $instance;
private function __construct() {} // Blokujemy domyślny konstruktor publiczny
private function __clone(){} //Uniemożliwia utworzenie kopii obiektu
public static function getInstance ()
{
//Wersja czytelniejsza
if (self::$instance === null) {
self::$instance = new Singleton();
}
return self::$instance;
//Wersja z operatorem ternarnym
return (self::$instance === null) ? self::$instance = new Singleton() : self::$instance;
}
}
// Pobieramy instancję
$singleton = Singleton::getInstance();
?>
ActionScript 3
edytujRozwiązanie 1
edytuj
package
{
public class Singleton
{
private static var singleton : Singleton
public static function getInstance() : Singleton
{
if ( singleton == null )
singleton = new Singleton( arguments.callee );
return singleton;
}
//NOTE: AS3 nie pozwala na tworzenie prywatnych, czy chronionych konstruktorów
public function Singleton( caller : Function = null )
{
if( caller != Singleton.getInstance )
throw new Error ("Singleton is a singleton class, use getInstance() instead");
if ( Singleton.singleton != null )
throw new Error( "Only one Singleton instance should be instantiated" );
//reszta kodu tutaj
}
}
}
Rozwiązanie 2
edytuj
package {
public final class Singleton {
private static var instance:Singleton = new Singleton();
public function Singleton() {
if( instance ) throw new Error( "Dostęp do klasy jedynie za pośrednictwem metody Singleton.getInstance()" );
}
public static function getInstance():Singleton {
return instance;
}
}
}
C#
edytujRozwiązanie 1
edytujsealed class Singleton {
private static readonly Singleton instance = new Singleton();
private Singleton() {
}
static Singleton() {
}
public static Singleton Instance {
get {
return instance;
}
}
}
Rozwiązanie 2 (dla C# 2.0 i nowszych)
edytujpublic class Singleton<T> where T : class, new()
{
private static readonly object syncLock = new object();
private static T instance;
protected Singleton()
{
}
public static T Instance
{
get
{
if (instance == null)
{
lock (syncLock)
{
if (instance == null)
{
instance = new T();
}
}
}
return instance;
}
}
}
C++
edytuj //Definicja
class singleton
{
private:
singleton() {}
singleton(const singleton &);
singleton& operator=(const singleton&);
~singleton() {}
public:
std::string method() { return "singleton pattern"; }
static singleton& getInstance()
{
//Inicjalizacja statycznego obiektu.
//Obiekt zostanie utworzony przy pierwszym wywołaniu tej metody
//i tylko wtedy nastąpi inicjalizacja przy pomocy konstruktora.
//Każde następne wywołanie jedynie zwróci referencję tego obiektu.
static singleton instance;
return instance;
}
};
//Uzycie
std::cout << singleton::getInstance().method();
Pascal
edytuj//Free Pascal Compiler version 2.6.2
program singleton;
{$mode objfpc}
uses
classes, sysutils;
type
TSingleton = class(TObject)
private
FInstance: TSingleton; static;
public
Field: integer;
class function GetInstance: TSingleton; static;
end;
class function TSingleton.GetInstance: TSingleton;
begin
if not assigned(FInstance) then
FInstance := TSingleton.Create;
result := FInstance;
end;
//Przykład użycia
var
s1, s2: TSingleton;
begin
s1 := TSingleton.GetInstance;
s1.Field := 10;
s2 := TSingleton.GetInstance;
Writeln(s2.Field);
s2.Field := 20;
Writeln(s1.Field);
Writeln(s1 = s2);
s1.Free;
end.
Python
edytuj class Singleton(object):
def __new__(type):
if not '_instancja' in type.__dict__:
type._instancja = object.__new__(type)
return type._instancja
# przykład
a=Singleton()
a.toto = 1234
b=Singleton()
print b.toto
b.toto = 4321
print a.toto
# TAKIE SAME, ta sama instancja klasy
print id(a),id(b)
Objective-C
edytuj#import "Singleton.h"
@implementation Singleton
//wskaźnik do instancji klasy
static Singleton *sharedSingleton = nil;
- (id)init {
if ( self = [super init] ) {
return self;
} else {
return nil;
}
}
+ (Singleton*)sharedInstance {
@synchronized(self) {
if (sharedSingleton == nil) {
[[self alloc] init];
}
}
return sharedSingleton;
}
+ (id)allocWithZone:(NSZone *)zone {
@synchronized(self) {
if (sharedSingleton == nil) {
sharedSingleton = [super allocWithZone:zone];
return sharedSingleton;
}
}
return nil;
}
- (id)copyWithZone:(NSZone *)zone {
return self;
}
- (id)retain {
return self;
}
- (unsigned)retainCount {
return UINT_MAX;
}
- (void)release {
}
- (id)autorelease {
return self;
}
- (void) dealloc {
}
@end