Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   3 Schichtversuch (https://www.delphipraxis.net/173957-3-schichtversuch.html)

Cyberdine 26. Mär 2013 09:53

3 Schichtversuch
 
Hallo,
zuzeit befasse ich mit 3 Schichtarchitektur unter Delphi und bin da auf folgendes Problem gestoßen. Beim instanzieren des Mittleren und des untern DB(ADO)-Objekts kommt eine Fehlermeldung die besagt, dass ich Parameter bräuchte bei .Create obwohl ich garkeinen Konstruktor und somit keine Parameter implementiert habe.
Hier der Quelltext dazu

Delphi-Quellcode:

type
  TForm1 = class(TForm)
    PageControl1: TPageControl;
    TabSheet1: TTabSheet;
    TabSheet2: TTabSheet;
    ADOQuery: TADOQuery;
    EditVVertragsNr: TEdit;
    LabelVVertragsNr: TLabel;
    LabelVEFDatum: TLabel;
    DTPVEFDatum: TDateTimePicker;
    ButtonVSuchen: TButton;
    procedure FormShow(Sender: TObject);
    procedure ButtonVSuchenClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

type
  TVertrag = class(TForm1)
  private
    { Private-Deklarationen }
    iVertragsID : integer;
    sVertragsNummer : string;
    dErfasstAm : TDate;
  public
    { Public-Deklarationen }
    procedure SetVertragsNummer(VNr : string);
    procedure SetErfasstAm(EfDate : TDate);
    function GetVertragsNummer : string;
    function GetErfasstAm : TDate;
  end;

type TDBVertrag = class(TVertrag)
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
    function Suchen(qry : TADOQuery) : boolean; Overload;
end;

var
  Form1: TForm1;
  Vertrag : TVertrag;
  DBVertrag : TDBVertrag;

implementation

{$R *.dfm}

{ TVertrag }

// Vertragsdatum für die GUI-Schicht auslesen
function TVertrag.GetErfasstAm: TDate;
begin
  GetErfasstAm := dErfasstAm;
end;

// Vertragsnummer für die GUI-Schicht auslesen
function TVertrag.GetVertragsNummer: string;
begin
  GetVertragsNummer := sVertragsNummer;
end;

// Vertragsdatum in der Mittelschicht eintragen
procedure TVertrag.SetErfasstAm(EfDate: TDate);
begin
  dErfasstAm := EfDate;
end;

// Vertragsnummer in der Mittelschicht eintragen
procedure TVertrag.SetVertragsNummer(VNr: string);
begin
  sVertragsNummer := VNr;
end;

{ TDBVertrag }

// ADO - Vertrag suchen
function TDBVertrag.Suchen(qry: TADOQuery): boolean;
var
  statement : string;
  bcheck : boolean;
begin
  bcheck := true;
  with qry do
  begin
    Close;
    SQL.Clear;
    statement := 'select * from VERTRAG order by ERFASSTAM asc';
    SQL.Text := statement;
  end;
  qry.ExecSQL;
  DMAdo.ADOConnection.BeginTrans;
  DMAdo.ADOConnection.CommitTrans;
  qry.Open;
  exit(true);
end;

// Button Vertrag suchen
procedure TForm1.ButtonVSuchenClick(Sender: TObject);
var
  stmp : string;
begin
  stmp := '';
  if (DBVertrag.Suchen(ADOQuery = true)) then
  begin
    stmp := ADOQuery.FieldByName('VERTRAGSNR').Value;
    Vertrag.SetVertragsNummer(stmp);
    EditVVertragsNr.Text := Vertrag.GetVertragsNummer;
  end;

end;

// Hauptformular laden
procedure TForm1.FormShow(Sender: TObject);
var
  bError : boolean;
  sVerbindungsString : string;
begin
  DMAdo := sVerbindungsString;
  try
    if(DMAdo.ADOConnection.Connected) then
      Exit;

    DMAdo.ADOConnection.Open;
  except // Benutzername oder Passwort nicht korrekt
    bError := False;
  end;
  ADOQuery.Connection := DMAdo.ADOConnection;

  Vertrag := TVertrag.Create();
  DBVertrag := TDBVertrag.Create();
end;

end.

Neutral General 26. Mär 2013 09:57

AW: 3 Schichtversuch
 
Hallo,

Ganz einfach: Leite deinen TVertrag nicht von TForm1 ab.
Das macht einfach überhaupt keinen Sinn. Daher hast du auch den constructor von TForm geerbt.

Einfach

Delphi-Quellcode:
TVertrag = class(TForm1)
in

Delphi-Quellcode:
TVertrag = class
ändern

Furtbichler 26. Mär 2013 11:09

AW: 3 Schichtversuch
 
Ich weiß jetzt auch nicht so genau, ob das das eine 3-Schicht Architektur ist (3-Tier). So wie ich das verstanden habe, sind die Schichten so aufgeteilt
1. Datenbank
2. Applikationsserver mit Mittelschicht, der sich mit der/den Datenbanken verbindet
3. Client, die die Daten von der 2.Schicht abholen und dorthin zurück schicken

Jedenfalls hab ich das immer so programmiert und das als 3-Tier verkauft.

Sir Rufo 26. Mär 2013 11:10

AW: 3 Schichtversuch
 
Irgendwie ist das aber kein 3-Schichten-Modell sondern MVC (Model-View-Controller) bzw. MVVM (Model-View-ViewModel)

Zitat:

Zitat von Furtbichler (Beitrag 1208863)
Ich weiß jetzt auch nicht so genau, ob das das eine 3-Schicht Architektur ist (3-Tier). So wie ich das verstanden habe, sind die Schichten so aufgeteilt
1. Datenbank
2. Applikationsserver mit Mittelschicht, der sich mit der/den Datenbanken verbindet
3. Client, die die Daten von der 2.Schicht abholen und dorthin zurück schicken

Jedenfalls hab ich das immer so programmiert und das als 3-Tier verkauft.

:thumb:

QuickAndDirty 26. Mär 2013 11:33

AW: 3 Schichtversuch
 
Zitat:

Zitat von Furtbichler (Beitrag 1208863)
Ich weiß jetzt auch nicht so genau, ob das das eine 3-Schicht Architektur ist (3-Tier). So wie ich das verstanden habe, sind die Schichten so aufgeteilt
1. Datenbank
2. Applikationsserver mit Mittelschicht, der sich mit der/den Datenbanken verbindet
3. Client, die die Daten von der 2.Schicht abholen und dorthin zurück schicken

Jedenfalls hab ich das immer so programmiert und das als 3-Tier verkauft.

Und ich dachte immer, dass das eine normale old schoolige Client-Server-Architektur ist...also kann ich an sowas 3-Tier-Architektur dran kleben?
Weil das hört sich schon viel weniger altbacken an als Client-Server-Architektur.

QuickAndDirty 26. Mär 2013 11:37

AW: 3 Schichtversuch
 
Zitat:

Zitat von Sir Rufo (Beitrag 1208864)
Irgendwie ist das aber kein 3-Schichten-Modell sondern MVC (Model-View-Controller) bzw. MVVM (Model-View-ViewModel)

???
Alles ohne Interfaces und mit globalen Variablen in einer Unit?

Sir Rufo 26. Mär 2013 11:37

AW: 3 Schichtversuch
 
Zitat:

Zitat von QuickAndDirty (Beitrag 1208873)
Zitat:

Zitat von Furtbichler (Beitrag 1208863)
Ich weiß jetzt auch nicht so genau, ob das das eine 3-Schicht Architektur ist (3-Tier). So wie ich das verstanden habe, sind die Schichten so aufgeteilt
1. Datenbank
2. Applikationsserver mit Mittelschicht, der sich mit der/den Datenbanken verbindet
3. Client, die die Daten von der 2.Schicht abholen und dorthin zurück schicken

Jedenfalls hab ich das immer so programmiert und das als 3-Tier verkauft.

Und ich dachte immer, dass das eine normale old schoolige Client-Server-Architektur ist...also kann ich an sowas 3-Tier-Architektur dran kleben?
Weil das hört sich schon viel weniger altbacken an als Client-Server-Architektur.

Eine 3-Schicht-Architektur ist auch eine Client-Server-Architektur.
Eine Client-Server-Architektur ist aber nicht auch automatisch eine 3-Schicht-Architektur

Sir Rufo 26. Mär 2013 11:38

AW: 3 Schichtversuch
 
Zitat:

Zitat von QuickAndDirty (Beitrag 1208875)
Zitat:

Zitat von Sir Rufo (Beitrag 1208864)
Irgendwie ist das aber kein 3-Schichten-Modell sondern MVC (Model-View-Controller) bzw. MVVM (Model-View-ViewModel)

???
Alles ohne Interfaces und mit globalen Variablen in einer Unit?

OK, ich hätte wohl eher schreiben sollen
Zitat:

... der Versuch ...
:mrgreen:

Aber das stand ja schon im Titel ;)

QuickAndDirty 26. Mär 2013 11:58

AW: 3 Schichtversuch
 
Zitat:

Zitat von Sir Rufo (Beitrag 1208879)
OK, ich hätte wohl eher schreiben sollen
Zitat:

... der Versuch ...
:mrgreen:

Aber das stand ja schon im Titel ;)

Es wird einem mit Delphi auch nicht leicht gemacht. Wäre es sinnvoll Muster/Demo Projekte für derartige Design Pattern in der CodeLib zur Verfügung zu stellen?
MVC, MVP, MVVM,...
Und eine Muster Projektgruppe für eine 3 Schicht Architektur?

Sir Rufo 26. Mär 2013 12:03

AW: 3 Schichtversuch
 
Zitat:

Zitat von QuickAndDirty (Beitrag 1208894)
Zitat:

Zitat von Sir Rufo (Beitrag 1208879)
OK, ich hätte wohl eher schreiben sollen
Zitat:

... der Versuch ...
:mrgreen:

Aber das stand ja schon im Titel ;)

Es wird einem mit Delphi auch nicht leicht gemacht. Wäre es sinnvoll Muster/Demo Projekte für derartige Design Pattern in der CodeLib zur Verfügung zu stellen?
MVC, MVP, MVVM,...
Und eine Muster Projektgruppe für eine 3 Schicht Architektur?

Nun es wird nicht unbedingt erschwert, aber der RAD Ansatz verleitet halt den Weg des geringsten Wiederstands zu gehen ;)

Sinnvoll und wünschenswert wäre sowas durchaus

Cyberdine 26. Mär 2013 15:54

AW: 3 Schichtversuch
 
Das Problem mit "getrennten" Schichten seh ich hier

Delphi-Quellcode:
// Button Vertrag suchen
procedure TForm1.ButtonVSuchenClick(Sender: TObject);
var
  stmp : string;
begin
  stmp := '';
  if (DBVertrag.Suchen(ADOQuery = true)) then
  begin
    stmp := ADOQuery.FieldByName('VERTRAGSNR').Value;
    Vertrag.SetVertragsNummer(stmp);
    EditVVertragsNr.Text := Vertrag.GetVertragsNummer;
  end;

end;
Da verschwimmen alle 3 Schichten zusammen aber eigentlich sollten alle 3 Schichten klar getrennt sein. Ich frage mich nur, wie trenn ich das jetzt sauber?
Irgendwie muß ja Die Vertragsnummer "sauber" von der DB (ADO) Schicht über die Mittelschicht zum Frontend kommen.

DeddyH 26. Mär 2013 15:59

AW: 3 Schichtversuch
 
Wieso suchst Du nicht über die Vertrags-Klasse?

BTW: Bitte nicht mit true/false vergleichen, das ist ein immer wieder aufkommendes Thema.

Cyberdine 26. Mär 2013 16:06

AW: 3 Schichtversuch
 
Also währe das so sauberer?

Delphi-Quellcode:
// Button Vertrag suchen
procedure TForm1.ButtonVSuchenClick(Sender: TObject);
begin
  Vertrag.Suchen;
  EditVVertragsNr.Text := Vertrag.GetVertragsNummer;
end;
Vertrag.Suchen leitet die Anfrage weiter an die DB(ADO)-Schicht, von dieser wird dann mit "Set" die Vertragsnummer im Objekt Vertrag aus der Query gesetzt(übertragen) und hier bei ButtonSuchen letztendlich an das Frontend weitergegeben.

DeddyH 26. Mär 2013 16:12

AW: 3 Schichtversuch
 
Japp. Die Präsentationsschicht kennt (im Idealfall) nur die Logikschicht und diese wiederum nur die Datenhaltungsschicht.

Cyberdine 26. Mär 2013 16:18

AW: 3 Schichtversuch
 
Ok vielen Dank für die Info :thumb:

Cyberdine 30. Mär 2013 15:12

AW: 3 Schichtversuch
 
Hallo,
hab mich mal weiter an den Feinheiten der OOP versucht und bin da auf folgendes gestoßen. Und zwar vererbe ich an die Logikschicht die DB-Zugriffsschicht, auf deren Methoden wie hier z.B. speichern nur die Logikschicht zugreifen kann. Damit die Methode der DB-Schicht nur für die Logikschicht sichtbar ist habe ich "strict protected" angewand (strict protected - hierauf kann man nur innerhalb der Klasse und ihrer Nachfahren zugreifen )
Allerdings kommt beim compilieren die Fehlermeldung das nicht auf "proteced Symbol Speichern" zugegriffen werden, die garnicht zu der Beschreibung paßt, da ja die Logikschicht der Nachfahre von TDBVertrag ist. Vorher hatte ich probiert die DB-Schicht als Nachfahren der Logikschicht anzugeben, aber das würde dann auch nicht zu der Beschreibung von strict protected paßen, da die Logikschicht auf eine Methode des Vorfahren zugreifen muß, damit die Daten in der DB-Schicht landen.

Code:
type
  TDBVertrag = class
  strict private
    { strict Private-Deklarationen }
    // Felder
    // Methoden
  strict protected
    { strict Protected-Deklarationen }
    // Felder
    // Methoden
    procedure Speichern(qry : TADOQuery); virtual;

  protected


  private
    { Private-Deklarationen }

  public
    { Public-Deklarationen }

  end;

Cyberdine 30. Mär 2013 15:32

AW: 3 Schichtversuch
 
Hab das Problem schon gefunden. Habe .Speichern direkt über die DB-Instanz aufgerufen anstatt über die geerbte Methode.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:04 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz