Biror narsa interfeysni qo'llab-quvvatlab turishini tekshirish mumkinmi?

Men Delphi XE2 dan foydalanmoqdaman. Hozirda ob'ektga asoslangan model mavjud va har bir model ob'ektida bir nechta tekshiruvchi bo'lishi mumkin. Validator generic abstrakt sinfining soddalashtirilgan bajarilishi. DoValidate-ni betaraf tekshiruv sinflari bekor qilishi mumkin va ular model ob'ektini suratga olish shart emas. Validator o'zining IValidator interfeysi yordamida ishlatiladi.

unit ObjectBasedValidator;

interface

uses
  System.SysUtils,
  System.Generics.Collections;

type
  TModelEntity = class
  end;

type
  IValidator = interface
    procedure Validate(aEntity: TModelEntity; aResult: string);
  end;

  TValidator = class(TInterfacedObject, IValidator)
  private
  protected
    procedure DoValidate(aEntity: T; aResult: string); virtual; abstract;
  public
    procedure Validate(aEntity: TModelEntity; aResult: string);
  end;

implementation

{ TValidator }

procedure TValidator.Validate(aEntity: TModelEntity; aResult: string);
begin
  if not (aEntity is T) then
    Exit;

  DoValidate(aEntity as T, aResult);
end;

end.

Endi ob'ekt modelini interfeysga o'zgartirishga harakat qilaman. Shuning uchun yangilangan tekshiruv birligi:

unit InterfaceBasedValidator;

interface

type
  IModelEntity = interface
  end;

type
  IValidator = interface
    procedure Validate(aEntity: IModelEntity; aResult: string);
  end;

  TValidator = class(TInterfacedObject, IValidator)
  private
  protected
    procedure DoValidate(aEntity: I; aResult: string); virtual; abstract;
  public
    procedure Validate(aEntity: IModelEntity; aResult: string);
  end;

implementation

{ TValidator }

procedure TValidator.Validate(aEntity: IModelEntity; aResult: string);
begin
 //The next line does not compiles
  if not (aEntity is I) then
    Exit;

  DoValidate(aEntity as I, aResult);
end;

end.

Derazam qilmaydigan qatorga izoh beraman. Shubhasiz, "I" umumiy turida ishlash uchun belgilangan GUID bo'lishi kerak, ammo bu talabni taqiqlash sifatida belgilashning hech qanday usuli yo'q.

Mumkin bo'lgan vaqtinchalik echim umumlashtiruvchi mavhum sinfdan foydalanmaslik va validatorda interfeysi surish bo'lishi mumkin, biroq kimdir buni qanday qilib bajarmaslik haqida fikrga ega ekanligiga qiziqaman.

2
Buning uchun, GUID taqiqlashini ko'rsatishning bir yo'li bo'lishi kerak deb o'ylayman.
qo'shib qo'ydi muallif David Heffernan, manba

1 javoblar

Quyidagi ishlar ko'rinadi:

uses
  SysUtils, TypInfo;

{ TValidator }

procedure TValidator.Validate(const aEntity: IModelEntity; aResult: string);
var
  intf: I;
begin
  if not Supports(aEntity, GetTypeData(TypeInfo(I))^.Guid, intf) then
    Exit;

  DoValidate(intf, aResult);
end;
1
qo'shib qo'ydi
Men ishonch hosil qilish uchun RTL kodini bosib o'tishim kerak edi, lekin agar null GUID so'raganda umumiy IInterface/IUnknown interfeysi ko'rsatgichini qaytarib beradigan bo'lsa.
qo'shib qo'ydi muallif Remy Lebeau, manba
I da GUID yo'q bo'lganda qobiliyatsiz rejim nima?
qo'shib qo'ydi muallif David Heffernan, manba
Bunday vaziyatda faqat intf ko'rinishida qanday taxmin qilish mumkin.
qo'shib qo'ydi muallif David Heffernan, manba
GUID - null ({00000000-0000-0000-0000-000000000000}), ammo qiziqarli tarzda qo'llab-quvvatlaydi, bu hali ham qaytaradi.
qo'shib qo'ydi muallif Ondrej Kelle, manba