Praktik terbaik untuk menerapkan MVVM dan MVC di delphi Pascal

10

Saya seorang programmer pascal Delphi, saya menggunakan Embarcadero delphi XE terbaru, dan saya ingin mengambil keuntungan dari pola desain seperti Model view controller dan model view view-model.

Namun, tampaknya tidak banyak di web tentang praktik terbaik untuk melakukan ini secara pascal. Sebagian besar contoh yang dapat saya temukan adalah dalam C # dan beberapa fitur bahasa tidak hadir dalam pascal, yang berarti saya mungkin harus menemukan cara untuk mengimplementasikan fitur-fitur tersebut.

Saya mencoba mengadaptasi kode dari artikel ini di sini

Saya akan membuat daftar masalah yang saya hadapi

  • Jenis tidak dapat dibatalkan

Pascal tidak memiliki tipe yang dapat dibatalkan karena C # melakukannya sehingga saya telah membuat sendiri.

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;

di bagian implementasi

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;
  • Dapatkan / Tetapkan untuk properti

Sekarang saya memiliki tipe nullable saya dapat membuat properti nullable Namun ia datang dengan beberapa bau kode

misalnya jika saya buat

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

di bagian implementasi

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;

Ini baik-baik saja tetapi ketika datang untuk menggunakan properti ini saya tidak bisa hanya menggunakan

myFoo.Bar.Value: = 1;

Saya harus menggunakan

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

Yang agak berantakan. Saya kira mungkin tidak ada yang bisa saya lakukan tentang ini.

  • Referensi Lingkar

Saya suka memisahkan kelas menjadi unit yang berbeda.

yaitu: struktur

menjaga antarmuka pengguna terpisah dari logika kontrol dan model serta lapisan logika data.

Saya dapat memiliki situasi di mana 2 kelas dapat saling referensi. Meskipun ini adalah situasi yang sebagian besar ingin saya hindari, ada saat-saat di mana ini diperlukan.

sebagai contoh

unit u_A;

interface

uses
  u_B
  ;

type 
  TA = class
    public
       Foo : TB;
  end;

implementation

end;

dan unit lain

unit u_B;

interface

uses
  u_A
  ;

type 
  TB = class
    public
       Foo : TA;
  end;

implementation

end;

Kode ini rusak karena dua kelas termasuk satu sama lain dan ini tidak dapat dilakukan secara pascal. Ini bukan masalah di C #. Solusi yang dapat saya pikirkan: 1. memasukkan kedua kelas dalam unit yang sama, meskipun ini merupakan masalah jika saya tidak berpikir ini sesuai dengan desain. 2. Buat antarmuka orangtua lain untuk B dan mewarisi B dari itu, maka ini akan mengelilinginya. Meskipun ini berantakan untuk tugas yang sangat sederhana.

  • Kelas statis

Tidak ada kelas statis di Delphi, ini berguna untuk kelas kontrol.

  • Kelas-kelas Container terbaik untuk digunakan dalam Delphi

Saya saat ini menggunakan TList dan TObjectList dalam Generics.Collections. Mereka diperkenalkan di Delphi XE. Saya harap ini adalah yang terbaik untuk digunakan karena delphi 7 tampaknya tidak memiliki pilihan yang baik.

Saya masih memikirkan event handler dan masalah apa pun yang mungkin muncul di sana. Mungkin ada beberapa masalah lain yang belum saya pikirkan.

Terima kasih atas sarannya.

sa
sumber
Saya awalnya mengajukan pertanyaan ini pada tinjauan kode tetapi disarankan agar saya memposting di sini.
sav

Jawaban:

9

Anda harus melihat ke dalam Spring4D karena sudah mengandung tipe nullable (implementasi yang sama seperti milik Anda dengan sedikit kelebihan operator) dan jauh lebih kuat dari tipe pengumpulan di RTL. Mereka juga berbasis antarmuka yang sangat berguna karena Anda tidak perlu khawatir tentang manajemen seumur hidup terutama ketika melewati mereka.

Untuk masalah referensi silang saya menyarankan pengkodean terhadap antarmuka dan menggunakan ini sebagai referensi dalam implementasi lain daripada 2 implementasi yang saling mengenal.

Adapun bagian MVVM Anda mungkin melihat ke DSharp yang memiliki versi pertama port Micro Caliburn untuk Delphi. Ini adalah tahap yang sangat awal dan sulit didokumentasikan tetapi Anda mungkin mendapatkan beberapa ide bagaimana mencapai MVVM di Delphi menggunakan GUI dan logika bisnis yang terhubung dengan binding data. Majalah Blaise Pascal memiliki dua artikel tentang itu jika Anda lebih tertarik.

PS Saya kira Anda berarti Anda menggunakan XE6 karena itu adalah versi terbaru.

Stefan Glienke
sumber