VBScript(经典)ASP中的单例模式

时间:2020-12-19 01:34:20

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

我刚刚创建了一个FirePHP服务器端库的经典ASP版本,它可以与常规的旧FirePHP控制台一起使用。

see the Github project

看看Github项目

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.

如果甚至可以创建静态方法,我不知道如何使用这种语言中的单例模式。

3 个解决方案

#1


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.

您可以通过将实例添加到应用程序对象中来创建单例。只要Web应用程序正在运行,它就会在所有会话*享。

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.

重要提示:上面的示例只是模拟您如何做到这一点。

#2


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

Singleton实际上被一些人视为反模式....

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.

您可以将类重命名为cFireASP,使日志方法成为默认函数,并在您的包含文件中创建一个全局FALog实例。这为您提供了相同的API,其优点是您可以将引用传递给FALog实例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.

提示:您引用类中的响应对象,这将使单元测试变得困难。使用依赖注入或所述servicelocator将类与其全局环境分开。

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)
....

#3


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

因为我不认为VBScript语言结构使得它可以自然地使用类,所以我宁愿使用以下两个方法之一:

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

为应用程序范围的OnStart事件创建处理程序,然后加载该类的单个实例并将其分配给Application变量。由于此事件是应用程序启动时运行的第一个代码,因此您可以假设实例将始终加载。 aproach的优点是不必在将使用sigleton对象的页面上包含任何文件(因为Application.Context可用于所有ASP文件):在Global.asa中创建单例实例

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

use the singleton instance in "anyfile.asp":

使用“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.

创建一个函数来返回单例变量。如果已将obejct分配给Apllication.Context变量,则只返回它,如果不是,则在返回之前加载并分配。这种方法的优点是实例直到第一次使用时才会创建。由于我总是通过#include指令加载我的库,这对我来说没问题,并且是我的首选方式。

create the function to return singleton instance in myLib.inc

创建函数以在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" -->

使用“anyfile.asp”中的单例实例:

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

#1


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.

您可以通过将实例添加到应用程序对象中来创建单例。只要Web应用程序正在运行,它就会在所有会话*享。

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.

重要提示:上面的示例只是模拟您如何做到这一点。

#2


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

Singleton实际上被一些人视为反模式....

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.

您可以将类重命名为cFireASP,使日志方法成为默认函数,并在您的包含文件中创建一个全局FALog实例。这为您提供了相同的API,其优点是您可以将引用传递给FALog实例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.

提示:您引用类中的响应对象,这将使单元测试变得困难。使用依赖注入或所述servicelocator将类与其全局环境分开。

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)
....

#3


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

因为我不认为VBScript语言结构使得它可以自然地使用类,所以我宁愿使用以下两个方法之一:

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

为应用程序范围的OnStart事件创建处理程序,然后加载该类的单个实例并将其分配给Application变量。由于此事件是应用程序启动时运行的第一个代码,因此您可以假设实例将始终加载。 aproach的优点是不必在将使用sigleton对象的页面上包含任何文件(因为Application.Context可用于所有ASP文件):在Global.asa中创建单例实例

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

use the singleton instance in "anyfile.asp":

使用“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.

创建一个函数来返回单例变量。如果已将obejct分配给Apllication.Context变量,则只返回它,如果不是,则在返回之前加载并分配。这种方法的优点是实例直到第一次使用时才会创建。由于我总是通过#include指令加载我的库,这对我来说没问题,并且是我的首选方式。

create the function to return singleton instance in myLib.inc

创建函数以在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" -->

使用“anyfile.asp”中的单例实例:

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