Einzelnen Beitrag anzeigen

Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

AW: Immer Ärger mit ARC

  Alt 24. Okt 2014, 21:12
So ich habe hier mal eine Version, die jetzt auch mit FMX und Windows/Android funktioniert. Grundproblem ist hier die Besonderheit der MainForm (Basis der gesamten Anwendung) und dem Startverhalten bei den Mobile-Plattformen. Dadurch kommt es nur bei der MainForm zum Bruch der ganz strikten Trennung.
Delphi-Quellcode:
unit MVP.Base;

interface

type
  IView = interface
    ['{7B9FA290-778D-4E2F-8112-92ECACBEBB5A}']
  end;

  IModel = interface
    ['{E690A24A-C5D2-47B5-9DBC-45F7695AE167}']
  end;

  IPresenter = interface
    ['{A3BA4F9C-7E67-4D15-BE4A-514FBE85113B}']
  end;

  TModel = class abstract( TInterfacedObject, IModel )
  end;

  TPresenter<TViewType: IView; TModelType: IModel> = class abstract( TInterfacedObject, IPresenter )
  private
    FView: TViewType;
    FModel: TModelType;
  protected
    property View: TViewType read FView;
    property Model: TModelType read FModel;
  public
    constructor Create( AView: TViewType; AModel: TModelType ); virtual;
  end;

implementation

{ TPresenter<TViewType, TModelType> }

constructor TPresenter<TViewType, TModelType>.Create( AView: TViewType; AModel: TModelType );
begin
  inherited Create;
  FView := AView;
  FModel := AModel;
end;

end.
Delphi-Quellcode:
unit Interfaces.Main;

interface

uses
  MVP.Base;

type
  IMainView = interface( IView )
    ['{02D78A1F-3749-4A60-82A0-747E8F2D65FE}']
    procedure setHelloWorld( const Value: string );
  end;

  IMainModel = interface( IModel )
    ['{3F9AC82F-2AF6-485D-BF63-279A9C42B4AA}']
    function getHelloWorld: string;
  end;

  IMainPresenter = interface( IPresenter )
    ['{67D69F7B-539F-4124-B204-90A03973E26D}']
  end;

implementation

end.
Delphi-Quellcode:
unit Presenter.Main;

interface

uses
  MVP.Base, Interfaces.Main;

type
  TMainPresenter = class( TPresenter<IMainView, IMainModel>, IMainPresenter )

  public
    procedure AfterConstruction; override;
  end;

implementation

{ TMainPresenter }

procedure TMainPresenter.AfterConstruction;
begin
  inherited;
  View.setHelloWorld( Model.getHelloWorld );
end;

end.
Delphi-Quellcode:
unit Model.Main;

interface

uses
  MVP.Base,
  Interfaces.Main;

type
  TMainModel = class( TModel, IMainModel )
  public
    function getHelloWorld: string;
  end;

implementation

{ TMainModel }

function TMainModel.getHelloWorld: string;
begin
  Result := 'Hello World!';
end;

end.
Delphi-Quellcode:
unit Form.Main;

interface

uses
  MVP.Base,
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
  Interfaces.Main, FMX.Objects;

type
  TMainForm = class( TForm, IView, IMainView )
    Text1: TText;
  private
    FPresenter: IPresenter;
    procedure setHelloWorld( const Value: string );
  public
    procedure AfterConstruction; override;

  end;

var
  MainForm: TMainForm;

implementation

{$R *.fmx}

uses
  Presenter.Main, Model.Main;

{ TMainForm }

procedure TMainForm.AfterConstruction;
begin
  inherited;
  // Hier der Bruch, denn die View erstellt sich selbst den Presenter
  // Das könnte man auch noch auslagern mit einer Automatik, wo
  // der passende Presenter zur View erzeugt wird
  FPresenter := TMainPresenter.Create( Self, TMainModel.Create );
end;

procedure TMainForm.setHelloWorld( const Value: string );
begin
  Text1.Text := Value;
end;

end.
Delphi-Quellcode:
program dp_182444;

uses
  System.StartUpCopy,
  FMX.Forms,
  Form.Main in 'Form.Main.pas{MainForm},
  Interfaces.Main in 'Interfaces.Main.pas',
  Model.Main in 'Model.Main.pas',
  MVP.Base in 'MVP.Base.pas',
  Presenter.Main in 'Presenter.Main.pas';

{$R *.res}

begin
  ReportMemoryLeaksOnShutdown := True;
  Application.Initialize;
  Application.CreateForm(TMainForm, MainForm);
  Application.Run;

end.
Die Unit MVP.Base ist eigentlich nur Spielerei
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat