Einzelnen Beitrag anzeigen

Benutzerbild von sx2008
sx2008

Registriert seit: 15. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#2

AW: Dependency Injection vs Service Locator -- dynamisches Erzeugung von Objekten

  Alt 1. Aug 2012, 16:14
Du brauchst hier eine Fabrikmethode oder eine Factory.
Delphi-Quellcode:
// Fabrikmethode
// darf auch virtuell sein, damit man die implementierende Klasse von IUser
// ändern kann
function TUserFinder.CreateUser(UserID:Integer):IUser;
begin
  Result := TUser.Create(UserID);
end;

function TUserFinder.Find(const Username: string): IList<IUser>;
var
  Query : IDbQuery;
begin
  Query := FDatabase.GetQuery();
  Query.SQL := 'SELECT * FROM Users WHERE username = :username';
  Query.Parameters.Add(':username', Username);
  Query.Open();
  try
    Result := TList<IUser>.Create();
    for each Dataset in Query.Results do
    begin
      // User erzeugen mit Fabrikmethode
      User := CreateUser(Query['IdUser']);
      User.Username := Username;
      User.LastLogon := Query['LastLogon'];
      ...
      Result.Add(User);
    end;
  finally
    Query.Close();
  end;
end;
Mit einer Factory sieht das so aus:
Delphi-Quellcode:
TUserFactory = class(TObject)
public
  class function CreateUser(UserID:integer):IUser;virtual;
end

//===============
// Jenachdem ob nur in der Find-Methode neue IUser-Objekte erzeugt werden müssen,
// oder ob noch andere Methoden die Factory benötigen
// übergibt man die Factory als Parameter oder als Property der Klasse TUserFinder
function TUserFinder.Find(const Username: string; UF:TUserFactory): IList<IUser>;
var
  Query : IDbQuery;
begin
  Query := FDatabase.GetQuery();
  Query.SQL := 'SELECT * FROM Users WHERE username = :username';
  Query.Parameters.Add(':username', Username);
  Query.Open();
  try
    Result := TList<IUser>.Create();
    for each Dataset in Query.Results do
    begin
      // User erzeugen mit Factory
      User := UF.CreateUser(Query['IdUser']);
      User.Username := Username;
      User.LastLogon := Query['LastLogon'];
      ...
      Result.Add(User);
    end;
  finally
    Query.Close();
  end;
end;
Ein Service Locator ist ja auch eine Art Factory.
Allerdings kann ein Service Locator ALLE Arten von Objekten erzeugen,
während eine Factory auf eine bestimmte Gruppe von Objekten begrenzt ist.

Wenn man eine Factory wie oben im Beispiel übergibt ("injected"), dann bleibt der Code
weiterhin testbar und sauber.

Geändert von sx2008 ( 1. Aug 2012 um 16:17 Uhr)
  Mit Zitat antworten Zitat