views:

657

answers:

3

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.

A: 

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)
....
Joost Moesker
+2  A: 

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.

Michal
Am i right in thinking that this wouldn't require me to manually include the page on any other script i want to execute it on?
Jonathan
Which page do you mean? The "MySingleton" class needs to be available if you store an instance of it in the application. However if you store a primitive datatype in an application variable then you do not to include anything in your pages
Michal
I meant the latter, many thanks!
Jonathan
A: 

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()
Gerardo Lima