zoukankan      html  css  js  c++  java
  • 以接口为主导的设计中, 我在使用的框架模式


    在今后的 Delphi 中, 以接口、结构为主的设计应该会越来越多, 因为这样太方便了.

    System.RegularExpressions 就是以结构为主体设计的非常好的示范; 但更多东西使用接口会更合适.

    有见过他人早就使用接口写程序, 从手头的这个程序开始我才开始使用.

    现在基本总结出四种框架模式: 1、直接实现; 2、间接实现(或叫继承实现); 3、覆盖实现; 4、委托实现.

    一、直接实现:

    下例中虽有 TMy1、TMy2, 但在具体应用中使用的应是 IMy1、IMy2, 这就是我所谓的以接口为主导.
    TMy1、TMy2 直接实现了所属接口的所有方法, 这是我所谓的直接实现.
    这样可能会有代码重复, 但如果程序很小, 还是挺实用的.

    unit Unit1;
    
    interface
    
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs;
    
    type
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
      end;
    
      IA = Interface
        procedure Method_A;
      end;
    
      IB = Interface(IA)
        procedure Method_B;
      end;
    
      IMy1 = Interface(IB)
        procedure Method_My1;
      end;
    
      IMy2 = Interface(IB)
        procedure Method_My2;
      end;
    
      TMy1 = class(TInterfacedObject, IMy1)
        procedure Method_A;
        procedure Method_B;
        procedure Method_My1;
      end;
    
      TMy2 = class(TInterfacedObject, IMy2)
        procedure Method_A;
        procedure Method_B;
        procedure Method_My2;
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    { TMy1 }
    
    procedure TMy1.Method_A;
    begin
      ShowMessage('A');
    end;
    
    procedure TMy1.Method_B;
    begin
      ShowMessage('B');
    end;
    
    procedure TMy1.Method_My1;
    begin
      ShowMessage('My1');
    end;
    
    { TMy2 }
    
    procedure TMy2.Method_A;
    begin
      ShowMessage('A');
    end;
    
    procedure TMy2.Method_B;
    begin
      ShowMessage('B');
    end;
    
    procedure TMy2.Method_My2;
    begin
      ShowMessage('My2');
    end;
    
    {测试}
    procedure TForm1.FormCreate(Sender: TObject);
    var
      v1: IMy1;
      v2: IMy2;
    begin
      v1 := TMy1.Create;
      v1.Method_A;
      v1.Method_B;
      v1.Method_My1;
    
      v2 := TMy2.Create;
      v2.Method_A;
      v2.Method_B;
      v2.Method_My2;
    end;
    
    end.
    


    二、间接实现:

    下面例子通过一个间接的 TB 类, 避免了 TMy1、TMy2 中可能会重复的代码.

    unit Unit1;
    
    interface
    
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs;
    
    type
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
      end;
    
      IA = Interface
        procedure Method_A;
      end;
    
      IB = Interface(IA)
        procedure Method_B;
      end;
    
      TB = class(TInterfacedObject, IB)
        procedure Method_A;
        procedure Method_B;
      end;
    
      IMy1 = Interface(IB)
        procedure Method_My1;
      end;
    
      IMy2 = Interface(IB)
        procedure Method_My2;
      end;
    
      TMy1 = class(TB, IMy1)
        procedure Method_My1;
      end;
    
      TMy2 = class(TB, IMy2)
        procedure Method_My2;
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    { TB }
    
    procedure TB.Method_A;
    begin
      ShowMessage('A');
    end;
    
    procedure TB.Method_B;
    begin
      ShowMessage('B');
    end;
    
    { TMy1 }
    
    procedure TMy1.Method_My1;
    begin
      ShowMessage('My1');
    end;
    
    { TMy2 }
    
    procedure TMy2.Method_My2;
    begin
      ShowMessage('My2');
    end;
    
    {测试}
    procedure TForm1.FormCreate(Sender: TObject);
    var
      v1: IMy1;
      v2: IMy2;
    begin
      v1 := TMy1.Create;
      v1.Method_A;
      v1.Method_B;
      v1.Method_My1;
    
      v2 := TMy2.Create;
      v2.Method_A;
      v2.Method_B;
      v2.Method_My2;
    end;
    
    end.
    


    三、覆盖实现:

    从 TB 继承的过程中当然也可以通过覆盖虚函数而实现多态, 下面的 TMy2 就这么做了.

    unit Unit1;
    
    interface
    
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs;
    
    type
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
      end;
    
      IA = Interface
        procedure Method_A;
      end;
    
      IB = Interface(IA)
        procedure Method_B;
      end;
    
      TB = class(TInterfacedObject, IB)
        procedure Method_A; virtual;
        procedure Method_B; virtual;
      end;
    
      IMy1 = Interface(IB)
        procedure Method_My1;
      end;
    
      IMy2 = Interface(IB)
        procedure Method_My2;
      end;
    
      TMy1 = class(TB, IMy1)
        procedure Method_My1;
      end;
    
      TMy2 = class(TB, IMy2)
        procedure Method_A; override;
        procedure Method_B; override;
        procedure Method_My2;
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.dfm}
    
    { TB }
    
    procedure TB.Method_A;
    begin
      ShowMessage('A');
    end;
    
    procedure TB.Method_B;
    begin
      ShowMessage('B');
    end;
    
    { TMy1 }
    
    procedure TMy1.Method_My1;
    begin
      ShowMessage('My1');
    end;
    
    { TMy2 }
    
    procedure TMy2.Method_A;
    begin
      ShowMessage('A_My2');
    end;
    
    procedure TMy2.Method_B;
    begin
      ShowMessage('B_My2');
    end;
    
    procedure TMy2.Method_My2;
    begin
      ShowMessage('My2');
    end;
    
    {测试}
    procedure TForm1.FormCreate(Sender: TObject);
    var
      v1: IMy1;
      v2: IMy2;
    begin
      v1 := TMy1.Create;
      v1.Method_A;
      v1.Method_B;
      v1.Method_My1;
    
      v2 := TMy2.Create;
      v2.Method_A;
      v2.Method_B;
      v2.Method_My2;
    end;
    
    end.
    


    四、委托实现:

    接口中的方法是肯定要实现的, 但也可以通过 implements 关键字借用(或叫委托)其它的实现;
    但, 官方文档说这只适用于 Win32. 就是说这种方法在 Win64 和其它系统都不行, 还学它干嘛?

  • 相关阅读:
    Java常用API(Arrays类)
    Java常用API(String类)
    Java常用API(Random类)
    Java匿名对象介绍
    Qt串口实现921600波特率的方法
    Qthread实现多线程操作
    小品QIODevice::Text参数
    Qt串口通信
    Linux下挂载新的磁盘
    互斥锁陷阱:优先级反转、死锁
  • 原文地址:https://www.cnblogs.com/del/p/2311077.html
Copyright © 2011-2022 走看看