Frage

Delphi (und wahrscheinlich viele andere Sprachen) hat Klasse Helfer. Diese bieten eine Möglichkeit, fügen Sie zusätzliche Methoden zu einer vorhandenen Klasse. Ohne eine Unterklasse zu machen.

Also, was sind gute Einsatzmöglichkeiten für Klasse Helfer?

War es hilfreich?

Lösung

Ich bin mit ihnen:

  • VCL-Klassen verbessern.
  • Um Methoden zur TStrings Klasse hinzufügen, damit ich die gleichen Methoden in meine abgeleiteten Listen und in TStringList.

    TGpStringListHelper = class helper for TStringList
    public
      function  Last: string;
      function  Contains(const s: string): boolean;
      function  FetchObject(const s: string): TObject;
      procedure Sort;
      procedure Remove(const s: string);
    end; { TGpStringListHelper }
    
  • Um den Zugriff auf Datensatzfelder und entfernen Gießen .

Andere Tipps

Zuerst war ich irgendwie skeptisch über Klassen Helfer. Aber dann las ich einen interessanten Blogeintrag und ich bin jetzt überzeugt, dass sie in der Tat nützlich sind.

Zum Beispiel, wenn Sie eine vorhandene Instanz Klasse zusätzliche Funktionalität wollen und aus irgendeinem Grund sind Sie nicht in der Lage die vorhandene Quelle zu ändern. Sie können eine Klasse Helfer erstellen, um diese Funktionalität hinzuzufügen.

Beispiel:

type
  TStringsHelper = class helper for TStrings
  public
    function IsEmpty: Boolean;
  end;

function TStringsHelper.IsEmpty: Boolean;
begin
  Result := Count = 0;
end;

Jedes Mal wenn wir jetzt eine Instanz (eine Unterklasse) TStrings verwenden und TStringsHelper liegt im Rahmen. Wir haben Zugriff auf die Methode IsEmpty.

Beispiel:

procedure TForm1.Button1Click(Sender: TObject);
begin
  if Memo1.Lines.IsEmpty then
    Button1.Caption := 'Empty'
  else
    Button1.Caption := 'Filled';
end;

Weitere Informationen:

  • Klasse Helfer können in einer separaten Einheit gespeichert werden, so dass Sie Ihre eigenen raffinierte Klasse Helfer hinzufügen können. Achten Sie darauf, diese Einheiten zu geben, einen einfachen Namen wie ClassesHelpers für Helfer für die Klassen Einheit zu erinnern.
  • Es gibt auch Rekord Helfer.
  • Wenn es mehr Klassen Helfer im Umfang, einige Probleme erwarten, nur ein Helfer verwendet werden kann.

Das klingt sehr ähnlich wie Erweiterungsmethoden in C # 3 (und VB9). Die beste Verwendung ich für sie gesehen haben, ist die Erweiterungen IEnumerable<T> (und IQueryable<T>), die gegen willkürliche Sequenzen LINQ Arbeit lässt:

var query = someOriginalSequence.Where(person => person.Age > 18)
                                .OrderBy(person => person.Name)
                                .Select(person => person.Job);

(oder was auch immer, natürlich). All dies ist machbar, weil Erweiterungsmethoden Sie erlauben effektiv zusammen zu verketten ruft zu statischen Methoden, die die gleiche Art nehmen, wie sie zurück.

Sie sind sehr nützlich für die Plug-In. Zum Beispiel, sagen wir, einem Projekt eine bestimmte Datenstruktur definiert und es wird auf eine Disc in einer bestimmten Art und Weise gespeichert. Aber dann ein anderes Programm tut etwas sehr ähnlich, aber die Datendatei ist anders. Aber Sie wollen nicht Ihre EXE mit einem Bündel von Import-Code für eine Funktion aufblasen, dass viele Benutzer nicht verwenden müssen. Sie können ein Plugin-Framework verwenden und Importeure in ein Plugin setzen, die wie folgt funktionieren würde:

type
   TCompetitionToMyClass = class helper for TMyClass
   public
      constructor Convert(base: TCompetition);
   end;

Und dann den Konverter definieren. Eine Einschränkung: eine Klasse Helfer ist keine Klasse Freund . Diese Technik funktioniert nur, wenn es möglich ist, komplett aufgebaut, um ein neues TMyClass Objekt durch seine öffentlichen Methoden und Eigenschaften. Aber wenn Sie können, es funktioniert wirklich gut.

Das erste Mal, dass ich erinnere mich, zu erfahren, was Sie „Klasse Helfer“ sind Aufruf war beim Lernen Objective C. Kakao (Apples Objective C-Framework) verwendet, was genannt wird „Kategorien“.

Eine Kategorie können Sie eine vorhandene Klasse erweitern durch Hinzufügen Sie besitzen Methoden ohne Subclassing. In der Tat Cocoa fordert Sie dazu auf Subclassing wenn möglich zu vermeiden. Oft ist es sinnvoll zu Unterklasse, aber oft kann es mit Kategorien vermieden werden.

Ein gutes Beispiel für die Verwendung einer Kategorie in Cocoa ist das, was "Key Value-Code (KVC)" und nennt "Key Value Observing (KVO)."

Dieses System wird unter Verwendung implementiert zwei Kategorien (NSKeyValueCoding und NSKeyValueObserving). Diese Kategorien definieren und Methoden implementieren, die zu jeder Klasse hinzugefügt werden können, die Sie wollen. Zum Beispiel Kakao fügt hinzu: „Konformität“ zu KVC / KVO durch diese Kategorien unter Verwendung von Methoden zu NSArray hinzufügen wie:

- (id)valueForKey:(NSString *)key

NSArray Klasse hat weder eine Erklärung noch eine Implementierung dieser Methode. Jedoch durch die Verwendung der Kategorie. Sie können dieses Verfahren auf jedem NSArray Klasse aufrufen. Sie sind nicht zu gewinnen KVC / KVO Konformität erforderlich NSArray Unterklasse.

NSArray *myArray = [NSArray array]; // Make a new empty array
id myValue = [myArray valueForKey:@"name"]; // Call a method defined in the category

Mit dieser Technik ist es einfach KVC / KVO Unterstützung für Ihre eigenen Klassen hinzuzufügen. Java-Schnittstellen erlauben Sie Methodendeklarationen hinzuzufügen, aber Kategorien können Sie auch die tatsächlichen Implementierungen zu bestehenden Klassen hinzuzufügen.

Wie Gamecat zeigt, ist TStrings ein guter Kandidat Tipparbeit zu vermeiden:

type
  TMyObject = class
  public
    procedure DoSomething;
  end;

  TMyObjectStringsHelper = class helper for TStrings
  private
    function GetMyObject(const Name: string): TMyObject;
    procedure SetMyObject(const Name: string; const Value: TMyObject);
  public
    property MyObject[const Name: string]: TMyObject read GetMyObject write SetMyObject; default;
  end;

function TMyObjectStringsHelper.GetMyObject(const Name: string): TMyObject;
var
  idx: Integer;
begin
  idx := IndexOf(Name);
  if idx < 0 then
    result := nil
  else
    result := Objects[idx] as TMyObject;
end;

procedure TMyObjectStringsHelper.SetMyObject(const Name: string; const Value:
    TMyObject);
var
  idx: Integer;
begin
  idx := IndexOf(Name);
  if idx < 0 then
    AddObject(Name, Value)
  else
    Objects[idx] := Value;
end;

var
  lst: TStrings;
begin
  ...
  lst['MyName'] := TMyObject.Create; 
  ...
  lst['MyName'].DoSomething;
  ...
end;

Haben Sie jemals brauchen mehrzeilige Zeichenfolgen in der Registrierung zuzugreifen?

type
  TRegistryHelper = class helper for TRegistry
  public
    function ReadStrings(const ValueName: string): TStringDynArray;
  end;

function TRegistryHelper.ReadStrings(const ValueName: string): TStringDynArray;
var
  DataType: DWord;
  DataSize: DWord;
  Buf: PChar;
  P: PChar;
  Len: Integer;
  I: Integer;
begin
  result := nil;
  if RegQueryValueEx(CurrentKey, PChar(ValueName), nil, @DataType, nil, @DataSize) = ERROR_SUCCESS then begin
    if DataType = REG_MULTI_SZ then begin
      GetMem(Buf, DataSize + 2);
      try
        if RegQueryValueEx(CurrentKey, PChar(ValueName), nil, @DataType, PByte(Buf), @DataSize) = ERROR_SUCCESS then begin
          for I := 0 to 1 do begin
            if Buf[DataSize - 2] <> #0 then begin
              Buf[DataSize] := #0;
              Inc(DataSize);
            end;
          end;

          Len := 0;
          for I := 0 to DataSize - 1 do
            if Buf[I] = #0 then
              Inc(Len);
          Dec(Len);
          if Len > 0 then begin
            SetLength(result, Len);
            P := Buf;
            for I := 0 to Len - 1 do begin
              result[I] := StrPas(P);
              Inc(P, Length(P) + 1);
            end;
          end;
        end;
      finally
        FreeMem(Buf, DataSize);
      end;
    end;
  end;
end;

Ich würde nicht empfehlen, sie zu benutzen, da lese ich diesen Kommentar:

  

"Das größte Problem mit Klasse   Helfer aus dem p.o.v der mit ihnen   in Ihren eigenen Anwendungen, ist die Tatsache,   dass nur eine Klasse Helfer für einen bestimmten   Klasse kann jederzeit in ihrem Umfang sein.“   ... „Das heißt, wenn Sie zwei Helfer haben   in Umfang, wird nur eine zu erkennen   durch den Compiler. Sie werden nicht bekommen jede   Warnungen oder auch Hinweise zu allen anderen   Helfer, die versteckt werden können. "

http://davidglassborow.blogspot.com /2006/05/class-helpers-good-or-bad.html

Ich habe sie für die Bereitstellung von Klassenmethoden konsistent über Klassen gesehen: Hinzufügen Öffnen / Schließen und Show / Hide für alle Klassen eines bestimmten „Typ“ und nicht nur aktive und sichtbare Eigenschaften.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top