델파이 파스칼에서 MVVM 및 MVC 구현을위한 모범 사례


10

저는 델파이 파스칼 프로그래머이고, 최신 엠바 카데로 델파이 XE를 사용하고 있으며, 모델 뷰 컨트롤러 및 모델 뷰 뷰 모델과 같은 디자인 패턴을 이용하고 싶습니다.

그러나 웹 에서이 작업을 파스칼로 수행하는 모범 사례에 대해서는별로없는 것 같습니다. 내가 찾을 수있는 대부분의 예는 C #에 있으며 일부 언어 기능은 파스칼로 제공되지 않으므로 해당 기능을 구현할 방법을 찾아야 할 수도 있습니다.

이 기사의 코드를 여기 에 적용하려고합니다.

내가 직면 한 문제를 나열하겠습니다.

  • 널 입력 가능 유형

C #처럼 Pascal에는 nullable 유형이 없으므로 직접 만들었습니다.

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;
  • 속성 가져 오기 / 설정

이제 nullable 유형이 있으므로 nullable 속성을 만들 수 있지만 코드 냄새가 있습니다.

예를 들어 내가 만들면

    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;

이 클래스는 두 클래스가 서로를 포함하므로 파스칼에서는 수행 할 수 없기 때문에 중단되었습니다. 이것은 C #에서 그런 문제가 아닙니다. 내가 생각할 수있는 솔루션 : 1. 두 클래스를 같은 단위로 포함 시키십시오. 비록 이것이 디자인에 적합하지 않다면 문제가됩니다. 2. B에 대한 다른 부모 인터페이스를 만들고 그로부터 B를 상속하면 문제가 해결됩니다. 이 간단한 작업에는 지저분하지만.

  • 정적 클래스

Delphi에는 정적 클래스가 없으므로 제어 클래스에 유용합니다.

  • 델파이에서 사용할 최고의 컨테이너 클래스

나는 현재 Generics.Collections에서 TList와 TObjectList를 사용하고 있습니다 .Delphi XE에서 소개되었습니다. delphi 7에는 좋은 옵션이 없었기 때문에 이것이 최선의 방법이기를 바랍니다.

나는 여전히 이벤트 핸들러와 거기에서 발생할 수있는 문제에 대해 생각하고 있습니다. 아마도 내가 아직 생각하지 않은 다른 문제가있을 수 있습니다.

조언을 주셔서 감사합니다.


원래 코드 검토 에서이 질문을했지만 여기에 게시하는 것이 좋습니다.
sav

답변:


9

Spring4D에는 이미 널 입력 가능 유형 (추가 연산자 오버로드가 약간 적은 것과 유사한 구현)과 RTL의 것보다 더 강력한 콜렉션 유형이 포함되어 있으므로 Spring4D를 조사해야합니다. 또한 인터페이스 기반으로 제공되므로 특히 전달할 때 평생 관리에 대해 걱정할 필요가 없으므로 매우 편리합니다.

상호 참조 문제의 경우 인터페이스에 대한 코딩을 제안하고 서로 알고있는 두 가지 구현이 아닌 다른 구현에서 참조로 사용합니다.

MVVM 부분에 대해서는 Delphi 용 Caliburn Micro 포트의 첫 번째 버전이있는 DSharp를 살펴볼 수 있습니다. 초기 단계이며 문서화가 거의되지 않았지만 데이터 바인딩과 연결된 느슨하게 연결된 GUI 및 비즈니스 로직을 사용하여 Delphi에서 MVVM을 달성하는 방법에 대한 아이디어를 얻을 수 있습니다. Blaise Pascal 잡지에는 더 관심이 있다면 두 가지 기사가 있습니다.

추신 : XE6을 최신 버전으로 사용하고 있다고 생각합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.