Singleton深入浅出

上次我们简单介绍了静态成员,今天再延伸一下,看看设计模式中的单件模式(Singleton),我先照搬一些理论

Singleton-对象创建型模式

  • 意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

  • 动机:对于一些类来说,只有一个实例是很重要的。虽然系统中可以有许多打印机,但却只应该有一个打印假脱机(printer spooler),只应该有一个文件系统合一个窗口管理器。

  • 适用性
    1. 当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。
    2. 当这个唯一实例应该时通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。

  • 优点
    1.对唯一实例的受控访问
    2.缩小名空间
    3.允许对操作和表示的精化
    4.允许可变数目的实例
    5.比类操作更灵活

好了,看了这么多理论,厌倦了吧,下面我们看一些实例代码,典型的 Singleton 类如下

|

class Singleton
{
    public static Singleton Instance() = new Singleton();
}




Class Singleton
    Public Shared Instance As Singleton = New Singleton
End Class

C# | VB |

呵呵,够简单吧,当然实际应用时要复杂的多。回顾上面的理论,你可能已经注意到意图已经实现:通过 Singleton.Instance 我们已经有了访问它的全局访问点,静态成员Instance将返回类的唯一一个实例

可是实际中如何运用呢?据个例子,我们现在要做一个游戏,而游戏中需要加载一些Sprite,这些Sprite来自于一些bmp资源,为了提升性能并使程序中只有一个实例,这时我们考虑使用Singleton模式

class Sprites
{
    ///
1<summary>
2        /// Public field giving access the the instance of the Sprites class.
3        /// </summary>

public static readonly Sprites Instance = new Sprites();

    public Bitmap[] Tiles;

    ///
1<summary>
2        /// Private variable indicating if the sprites are loaded or not.
3        /// </summary>

private bool doneLoading;

    ///
1<summary>
2        /// Method loading the sprites from the assembly resource files
3        /// into the public bitmap array. To be sure the sprites are only loaded
4        /// once a private bool is set to true/false indicating if the sprites
5        /// have been loaded or not.
6        /// </summary>

public void LoadSprites() { if(!doneLoading) { Assembly asm = Assembly.GetExecutingAssembly(); Bitmap tiles = new Bitmap(asm.GetManifestResourceStream("game.Data.Sprites.Tiles.bmp"));

            //Parse the sprite strips into bitmap arrays.
            Tiles = ParseSpriteStrip(tiles);

            tiles.Dispose();
            doneLoading = true;
        }
    }

    ///
1<summary>
2        /// The constructor is made private to ensure that 
3        /// the class cannot be explicitly created
4        /// </summary>

private Sprites() {
}

}



Class Sprites

    '***********************************
    ' Public field giving access the the instance of the Sprites class.
    '***********************************
    Public Shared ReadOnly Instance As Sprites = New Sprites

    Public Tiles As Bitmap()

    '***********************************
    ' Private variable indicating if the sprites are loaded or not.
    '***********************************
    Private doneLoading As Boolean

    '***********************************
    ' Method loading the sprites from the assembly resource files
    ' into the public bitmap array. To be sure the sprites are only loaded
    ' once a private bool is set to true/false indicating if the sprites
    ' have been loaded or not.
    '***********************************
    Public Sub LoadSprites()
        If Not Me.doneLoading Then
            Dim asm As Assembly = Assembly.GetExecutingAssembly
            Dim tiles As New Bitmap(asm.GetManifestResourceStream("game.Data.Sprites.Tiles.bmp"))

            'Parse the sprite strips into bitmap arrays.
            Tiles = ParseSpriteStrip(tiles)

            tiles.Dispose
            Me.doneLoading = True
        End If
    End Sub

    '***********************************
    ' The constructor is made private to ensure that 
    ' the class cannot be explicitly created
    '***********************************
    Private Sub New()
    End Sub
    
End Class

C# | VB |

方法的调用 Sprites.Instance.LoadSprites()

小节: 通过Singleton,我们可以方便的使用类的实例方法,同时保证类的实例的唯一性。

Published At
Categories with Web编程
Tagged with
comments powered by Disqus