Problem:
VbClassic Classes don't support static methods, or a mechanism equivalent to overriding new(), so singletons can't be implemented in the way you would in C++.
MicrosoftDotNet appear to have Singleton built in to the framework, and an article on MSDN is located at http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/singletondespatt.asp
Context:
You are in a context where you would normally use a singleton but the implementation is in VisualBasic
Forces:
Solutions:
Related Patterns:
Singleton, FactoryMethod, IntentionSuggestingName, QualifiedClassName
Contributors: Stefan Kapusniak, JeffGrigg
But singletons 'can be implemented in VbClassic. It's just a different technique but the principle it's the same. All it really takes is a GlobalMultiuse class in the same ActiveX DLL as your Singleton class and a static module. I've described it below. :)
I have found that you can fake a lot of things using the different instancing properties of classes and standard modules in in VbClassic -- AlfredoChavez
Problem: Ensure a class only has one instance, and provide a global point of access to it.
Context: You are in a context where you would normally use a singleton but the implementation is in VisualBasic
Implementation: I don't know if someone came up with this one before me, but I recently had a programming problem in a project that quite fits the context and forces described for the singleton pattern in many online catalogs. So here's my take on it:
Public g_oSesion As CSesion
Public Property Get Sesion() As CSesion
If g_oSesion is Nothing Then
Set g_oSesion = New CSesion
' add any initialization code here,
' or better yet, IntroduceCreationObject here
End If
Set Sesion = g_oSesion
End Property
Private Sub Class_Terminate()
Set g_oSesion = Nothing
End Sub
Private implementation class, with a FactoryMethod:
public property get publicSomeClass() as privateSomeClass
static oInstance as privateSomeClass
if oInstance is nothing then
set oInstance = new privateSomeClass
end if
set publicClassName = oInstance
end property
publicSomeClass.someMethod
publicSomeClass.someProperty = "someString"
Set someReference = publicSomeClass.someObjectProperty
Additional thought: Make this an ActiveX DLL, and you can set the Instancing property to PublicNotCreatable, preventing DLL users from violating your creation rules. Consider setting the ThreadingModel to SingleThread too.
Contributors: StefanKapusniak, JeffGrigg
AbstractFactory class controls creation of implementation class, in ActiveX DLL for enforcement:
Like the above, except that it...
HandleBody approach:
The problem with this approach is it still relies on programmer's discipline not to instantiate the actual "private" class. I turn it around, and basically use the handle/body approach.
The result has many advantages
The only thing I can not find an easy way to do is to allow the classes to raise events. The only solution I have is for the body to maintain a collection of all created handles and call a"private" function in each instance telling them to raise their event.
Procedural ClassFactory function (not an object), with ActiveX protection of singleton class:
Here's how you do it. Slightly long winded, perhaps, but it works.
Create a new ActiveX DLL. Create in this your Singleton class with all its methods etc. Make sure you mark it 'Public not creatable'.
Add a .BAS module with one function:
Public Function getSingleton() as NameOfSingletonClass
Static Singleton as NameOfSingletonClass
If Singleton is Nothing then
set Singleton= New NameOfSingletonClass
' add any initialisation calls you want
endif
Set getSingleton = Singleton
Exit Function
End Function
Create a new class; ensure it is marked MultiUse. Give it one method:
public property Get SingletonInstance() as NameOfSingletonClass
Set SingletonInstance = getSingleton
end property
Add a reference to this AxDLL in your VB project and there's your singleton. What's so hard about that?
Took me < 5 mins to type into Wiki; add in compiles etc and there is about 10 mins overhead. -- SimonSmith