Delphi版设计模式之单例一

可能Delphi王朝真的没落了,在网上查了很久都是一些重复、陈旧、残缺不全的帖子,搞的像古代的武功秘籍一样,每次只能获取上篇或者下篇,而这些上下还有可能是残篇

设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。

引自菜鸟教程

从上面的话中不难看出,所谓的设计模式是针对一些常见问题总结出来的一套比较优质的解决方案,所以这个不限语言,所有语言通用

单例(Singleton)模式的定义:指一个类只有一个实例,且该类能自行创建这个实例的一种模式。例如,Windows 中只能打开一个任务管理器,这样可以避免因打开多个任务管理器窗口而造成内存资源的浪费,或出现各个窗口显示内容的不一致等错误。单例模式有 3 个特点

  • 单例类只有一个实例对象;
  • 该单例对象必须由单例类自行创建;
  • 单例类对外提供一个访问该单例的全局访问点;

有人说单例是所有设计模式中最简单的,我只能呵呵,单例模式就我知道的Java中的写法就有7、8种之多,Delphi的还在摸索学习,为了方便学习,案例还是以控制台应用的形式呈现,尽量减少库和单元的引用

代码实现

本文代码在DelphiXE10.4版本下测试通过

unit uCommonUtil;

interface

uses
    System.SysUtils;

type
   { TSingle }
    TSingle = class(TObject)
    private
        FNum: string;
    protected
    public
        constructor Create;
        class function GetInstance(): TSingle;
        class function NewInstance: TObject; override;
        procedure FreeInstance; override;
        property Str: string read FNum write FNum;
    published
    end;

implementation

var
    GlobalSingle: TSingle;
   { TSingle }

constructor TSingle.Create;
begin
    Str := '单例模式测试';
end;

procedure TSingle.FreeInstance;
begin
    inherited;
    GlobalSingle := nil;
end;

class function TSingle.GetInstance: TSingle;
begin
    //判断当前全局变量GlobalSingle不空则创建对象,这里在并发环境下存在安全隐患
    if GlobalSingle = nil then begin
        GlobalSingle := TSingle.create();
    end;
    Result := GlobalSingle;
end;

class function TSingle.NewInstance: TObject;
begin
    if GlobalSingle = nil then
        //重载方法通过父类  NewInstance方法获取对象,强制转换为 TSingle类型
        GlobalSingle := TSingle(inherited NewInstance);
    Result := GlobalSingle;
end;

end.

测试代码

program ProjectSingle;

{$APPTYPE CONSOLE}
{$R *.res}

uses
    System.SysUtils,
    System.Types,
    uCommonUtil in 'uCommonUtil.pas';

var
    P1, P2: Pointer;

begin

    try
        var com1 := TSingle.GetInstance();
        p1 := com1;
        P2 := TSingle.GetInstance();
        //通过输出的地址可见是同一个对象
        writeln(IntToStr(Integer(p2)));
        writeln(IntToStr(Integer(p1)));
    except
        on e: Exception do
            writeln(e.Message);
    end;

    readln;

end.

猜你喜欢

转载自blog.csdn.net/farmer_city/article/details/113102329