简体   繁体   中英

Singleton Pattern in VBScript (Classic) ASP

I've just created a Classic ASP version of the FirePHP server side library, that works with the regular old FirePHP console.

see the Github project

However in my implementation, i have to create a global to store the class instance.

I have no idea how to, if it is even possible to create static methods, and thus use the singleton pattern in this language.

You can create a singleton by adding your instance into the application object . It is shared amongst all sessions as long as the web app is running.

The following code should demonstrate it:

<%
class MySingleton
  public function getInstance()
    if not isObject(application("MySingleton")) then
      set application("MySingleton") = new MySingleton
    end if
    set getInstance = application("MySingleton")
  end sub
end class

'usage
set instance = (new MySingleton).getInstance()
%>

Important: The example above is just a simulation how you could do it.

Singleton is actually considered an anti-pattern by some....

You could rename the class to cFireASP , make the log method the default function and create one global FALog instance in youre include file. This gives you the same API with the advantage that you can pass references to the the FALog instance arround.

To decouple youre app further you could place the instanciation of this instance into a service locator. This way youre other classes don't have to reference various global instance directly, giving you another seam to seperate interface from implementation.

Tip: you reference the response object in your class which will make unittesting hard. Use depency injection or said servicelocator to separate the class from its global environment.

class cSomePageController
  public env
  private response, session, application, server, db_conn
  private sub class_initialize 
    set response = env.response
    set session = env.session
    set application = env.application
    set server = env.server
    set db_conn = env.db_conn
  end sub

  public sub handle_request(request)
    ...
  end sub      
end class
...

set controller = new cSomePageController
set env = new ASPenv    
set controller.env = env
call controller.handle_request(env.request)
' Alternatieve configuration for testing using a mock objects
set mock_env = new MockEnv
set controller.env = mock_env
call controller.handle_request(mock_env.request)
....

As I don't think VBScript language constructions make it natural working with classes, I'd rather use one of the two following aproaches:

1. create the singleton object in Appliction_OnStart event and load it to an Application.Context variable

Create a handler for application-wide OnStart event, then load the single instance of the class and assign it to an Application variable. As this event is the first code to run when the application starts, you can assume the instance will allways be loaded.

The advantage of the aproach is that is not necessary to include any file on pages that will use the sigleton object (as Application.Context is available to all ASP files):
create the singleton instance in Global.asa

Sub Application_OnStart
  Set Application.Contents("MySingleton") = new MySingleton
End Sub

use the singleton instance in " anyfile.asp ":

Dim obj : Set instance = Application.Contents("MySingleton")
obj.doAnyMethod()

2. use a function to access the singleton object

Create a function to return the singleton variable. If the obejct is already assigned to an Apllication.Context variable, just return it, if it's not, then load it and assign before returning.

The advantage of this aproach is that the instance is not created until the first time it's used. As I allways have my on library loaded by #include directives, this is no issue to me and would be my prefered way.

create the function to return singleton instance in myLib.inc

Function GetSingleton
  If IsEmpty(Application.Contents("MySingleton")) Then
    Set Application.Contents("MySingleton") = new MySingleton
  End If
  Set GetSingleton = Application.Contents("MySingleton")
End Function

use the singleton instance in " anyfile.asp ": <!--#include virtual="/myLib.inc" -->

Dim obj : Set instance = GetSingleton()
obj.doAnyMethod()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM