软件工程 设计模式学习之单例模式Singleton

技术交流,DH讲解.

单例模式一般都是在全局变量区存放一个变量,然后在创建的时候先看这个全局变量是否被赋值了,
如果没有就创建如果有就直接返回这个全局变量.
UML图:
singleton
要是不想被人创建对象的实例,那么一般的办法就是把构造方法设置成私有域.
好了,原理说了,我们就来看看代码怎么实现吧.

1 <?php
2  class PHPSinglton {
3 private $huangjacky;
4 private static $singleinstance;
5 private function __construct(){
6 $huangjacky='TheFiend';
7 }
8 static function GetInstance(){
9 if(!isset($singleinstance))
10 $singleinstance = new PHPSinglton();
11 return $singleinstance;
12 }
13 }
14  ?>

这个是PHP的单例模式的代码. 我们用一个静态变量来充当了全局变量.


接下来是C#的例子:

1 public class CSharpSingleton{
2 private static CSharpSingleton instance;
3 private CSharpSingleton(){
4 }
5 public static CSharpSingleton GetInstance(){
6 if (instance == null)
7 instance = new CSharpSingleton();
8 return instance;
9 }
10 }
11  private void button1_Click(object sender, EventArgs e)
12 {
13 CSharpSingleton a, b;
14 //a = new CSharpSingleton();这个会报错的
15   a = CSharpSingleton.GetInstance();
16 b = CSharpSingleton.GetInstance();
17 if (a==b)
18 { MessageBox.Show("Equals"); }
19 }
20  


现在PHP和C#的代码都有了.
我们该干什么了?嘿嘿,肯定是用我们喜欢的Delphi来实现一下:
由于Delphi里面如果我们将Constructor设置成private但是Delphi会悄悄的改回public
而且我们还发现不了...
有问题就要解决问题咯.看看
TSingleton = Class
Private
Class Var Instance: TSingleton;
Public
Class Function GetInstance: TSingleton;
Class Function NewInstance: TObject; Override;
Procedure FreeInstance; Override;
End;
我们会发现这里重载了TObject里面的2个方法.
Procedure TSingleton.FreeInstance;
Begin
Inherited;
Instance := Nil;
End;
Class Function TSingleton.GetInstance: TSingleton;
Begin
If Not Assigned( Instance ) Then
Instance := TSingleton.Create;
Result := Instance;
End;
Class Function TSingleton.NewInstance: TObject;
Begin
If Not Assigned( Instance ) Then
Instance := TSingleton( Inherited NewInstance );
Result := Instance;
End;
其实也是在这里判断静态变量是否创建了.
测试一下:
Procedure TForm2.Button1Click( Sender: TObject );
Var
A, B: TSingleton;
Begin
A := TSingleton.Create;
B := TSingleton.Create;
ShowMessageFmt( 'a:%8x,b:%8x', [ Integer( A ), Integer( B ) ] );
End;
我们可以看见Create后的A,B 以及GetInstance后的对象地址都是一样的.
我们可以看到Delphi要实现单例模式就是靠重载NewInstance方法,因为我们在前面文章看见,对象的构造过程中CreateInstance是最重要的一步.
适用性:

  • 当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。
  • 当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。
好的今天就说到这里,我是DH.

原文地址:https://www.cnblogs.com/huangjacky/p/1619781.html