Singletons . Yaklaşık 10-15 yıl önce, singletons, bilinmesi gereken en büyük tasarım deseniydi . Ancak, bugünlerde onlar üzerinde duruldu. Çoklu iş parçacığı için çok daha kolaydır, ancak kullanımlarını bir seferde bir iş parçacığıyla sınırlamanız gerekir; bu her zaman istediğiniz şey değildir. Yaşam sürelerini takip etmek, global değişkenler kadar zor.
Tipik bir singleton sınıfı şöyle görünecek:
class MyClass
{
private:
static MyClass* _instance;
MyClass() {} //private constructor
public:
static MyClass* getInstance();
void method();
};
...
MyClass* MyClass::_instance = NULL;
MyClass* MyClass::getInstance()
{
if(_instance == NULL)
_instance = new MyClass(); //Not thread-safe version
return _instance;
//Note that _instance is *never* deleted -
//it exists for the entire lifetime of the program!
}
Bağımlılık Enjeksiyonu (DI) . Bu sadece servisi yapıcı parametresi olarak geçirmek anlamına gelir. Bir sınıfa geçirebilmek için bir hizmet zaten mevcut olmalı, bu nedenle iki hizmetin birbirine güvenmesine imkan yok; vakaların% 98'inde istediğin budur (ve diğer% 2 için her zaman bir setWhatever()
yöntem oluşturabilir ve daha sonra hizmete geçebilirsin) . Bu nedenle, DI diğer seçeneklerle aynı bağlantı problemlerine sahip değildir. Çoklu iş parçacığı ile kullanılabilir, çünkü her iş parçacığı her hizmetin kendi örneğine sahip olabilir (ve yalnızca kesinlikle ihtiyacı olanları paylaşır). Ayrıca, onu önemsiyorsanız kod birimini test edilebilir kılar.
Bağımlılık enjeksiyonuyla ilgili sorun, daha fazla hafıza gerektirmesidir; Şimdi bir sınıfın her örneği, kullanacağı her hizmete referans gerektirir. Ayrıca, çok fazla hizmetiniz olduğunda kullanmak can sıkıcı hale gelir; Bu sorunu diğer dillerde azaltan çerçeveler var, fakat C ++ 'ın yansıma eksikliği nedeniyle, C ++' daki DI çerçeveleri sadece elle yapmaktan daha fazla iş yapma eğilimindedir.
//Example of dependency injection
class Tower
{
private:
MissileCreationService* _missileCreator;
CreepLocatorService* _creepLocator;
public:
Tower(MissileCreationService*, CreepLocatorService*);
}
//In order to create a tower, the creating-class must also have instances of
// MissileCreationService and CreepLocatorService; thus, if we want to
// add a new service to the Tower constructor, we must add it to the
// constructor of every class which creates a Tower as well!
//This is not a problem in languages like C# and Java, where you can use
// a framework to create an instance and inject automatically.
Başka bir örnek için bu sayfaya bakın (Ninject belgelerine, bir C # DI çerçevesi).
Bağımlılık enjeksiyonu, bu problem için olağan bir çözümdür ve StackOverflow.com'da bu gibi sorulara en çok cevap vereceğiniz cevaptır. DI, bir Kontrol Denetimi (IoC) türüdür .
Servis Bulucu . Temel olarak, sadece her hizmetin bir örneğini tutan bir sınıf. Yansımayı kullanarak yapabilir veya yeni bir servis oluşturmak istediğinizde ona yeni bir örnek ekleyebilirsiniz. Hala öncekiyle aynı problemin var - Sınıflar bu yer belirleyiciye nasıl erişiyor? - yukarıdaki yöntemlerden herhangi biriyle çözülebilir, ancak şimdi ServiceLocator
onlarca hizmet için değil, sadece sınıfınız için yapmanız yeterlidir . Bu yöntem, aynı zamanda böyle bir şeye önem veriyorsanız, test edilebilirdir.
Servis Belirleyiciler, başka bir Kontrol Tersine Çevirme (IoC) şeklidir. Genellikle, otomatik bağımlılık enjeksiyonunu yapan çerçevelerde bir servis bulucu da bulunur.
XNA (Microsoft'un C # oyun programlama çerçevesi) bir servis bulucu içerir; hakkında daha fazla bilgi edinmek için bu cevaba bakınız .