Найкращі практики впровадження MVVM та MVC в delphi Pascal


10

Я програміст паскаль Delphi, використовую останню версію Embarcadero delphi XE, і я хотів би скористатися такими моделями дизайну, як контролер перегляду моделі та модель подання виду.

Однак, в Інтернеті, здається, не так багато про кращі практики для цього в мові Pascal. Більшість прикладів, які я можу знайти, є на C #, а деякі мовні функції відсутні у мові pascal, а значить, можливо, мені доведеться знайти способи реалізації цих функцій.

Я намагаюся адаптувати код з цієї статті тут

Я перелічу проблеми, з якими я стикаюся

  • Зменшувані типи

Паскаль не має змінних типів, як це робить C #, тому я створив свій власний.

TNullable<T> = record
    strict private
      fHasValue : boolean;
      fValue : T;
      function GetValue:T;
      procedure SetValue(newValue : T);
    public
      property HasValue : boolean read fHasValue;
      property Value : T read GetValue write SetValue;
      procedure SetToNull;
    end;

у розділі впровадження

function TNullable<T>.GetValue:T;
begin
    if fHasValue then
    begin
        Result := fValue;
    end
    else raise Exception.Create('Value Not Set');
end;

procedure TNullable<T>.SetValue(newValue : T);
begin
    fValue := newValue;
    fHasValue := true;
end;

procedure TNullable<T>.SetToNull;
begin
    fHasValue := false;
end;
  • Отримати / встановити властивості

Тепер, коли я маю мінливий тип, я можу створювати мінливі властивості, проте він має деякі запахи коду

наприклад, якщо я створюю

    TFoo = class
      private
        function GetBar:TNullable<Integer>;
        procedure SetBar(x:TNullable<Integer>);
      public 
        property Bar : TNullable<Integer> read GetBar write SetBar;

у розділі впровадження

function TFoo.GetBar:TNullable<Integer>;
begin
    if **valueExists** then
    begin
        Result.Value := **the value**
    end else
    begin
        Result.SetToNull;
    end;
end;

procedure TFoo.SetBar(x:TNullable<Integer>);
begin
    if X.hasValue then
    begin
        //Store/show value here
    end else
    begin
        //handle null assignment here
    end;
end;

Це добре, але коли справа стосується використання цих властивостей, я не можу просто використовувати

myFoo.Bar.Value: = 1;

Я маю користуватися

var 
    myBar : TNullable<Integer>;
begin
    myBar.Value := 1;
    myFoo.Bar := myBar;
end;

Що трохи мідніше. Я гадаю, що з цим я нічого не можу зробити.

  • Кругові довідники

Мені подобається розділяти класи на різні одиниці.

тобто: будова

зберігаючи інтерфейс користувача окремо від логіки управління та логічного рівня моделі та даних.

У мене може виникнути ситуація, коли 2 класи можуть посилатися один на одного. Хоча це ситуація, якої я б хотів уникнути, здебільшого, є випадки, коли це потрібно.

наприклад

unit u_A;

interface

uses
  u_B
  ;

type 
  TA = class
    public
       Foo : TB;
  end;

implementation

end;

та інший підрозділ

unit u_B;

interface

uses
  u_A
  ;

type 
  TB = class
    public
       Foo : TA;
  end;

implementation

end;

Цей код порушений, оскільки два класи включають один одного, і це не можна зробити на мові Pascal. Це не така проблема в C #. Рішення, про які я можу придумати: 1. включайте обидва класи в один і той же підрозділ, хоча це проблема, якщо я не думаю, що це відповідає дизайну. 2. Створіть інший батьківський інтерфейс для B і успадкуйте B від цього, тоді це обходить. Хоча це безладно для такого простого завдання.

  • Статичні класи

Немає статичних класів у Delphi, вони корисні для класів управління.

  • Кращі класи для контейнерів, які можна використовувати в Delphi

В даний час я використовую TList і TObjectList в Generics.Collections Вони були представлені в Delphi XE, я сподіваюся, що це найкраще використовувати, оскільки delphi 7, схоже, не має жодних хороших варіантів.

Я все ще думаю про обробників подій та будь-які проблеми, які можуть виникнути там. Можливо, є якісь інші питання, про які я ще не замислювався.

Дякую за будь-яку пораду.


Я спочатку задав це питання при перегляді коду, але мені було запропоновано опублікувати тут.
сав

Відповіді:


9

Ви повинні заглянути в Spring4D, оскільки він вже містить нульові типи (схожа реалізація, як і ваша, з невеликою додатковою перевантаженням оператора) та спосіб більш потужних типів колекції, ніж у RTL. Вони також пов'язані між собою, що дуже зручно, тому що вам не доведеться турбуватися про управління протягом життя, особливо при передачі їх навколо.

Для проблем з перехресними посиланнями я пропоную кодування проти інтерфейсів і використовувати їх як посилання в іншій реалізації, а не в двох реалізаціях, що знають один одного.

Що стосується частини MVVM, ви можете заглянути в DSharp, який має першу версію порта Caliburn Micro для Delphi. Це дуже рання стадія і важко задокументована, але ви можете отримати деякі ідеї, як досягти MVVM у Delphi, використовуючи слабко пов'язаний графічний інтерфейс та бізнес-логіку, пов’язану з прив'язкою даних. У журналі Blaise Pascal було дві статті про нього, якщо вас більше цікавить.

PS Я думаю, ви маєте на увазі, що ви використовуєте XE6, як це остання версія.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.