HSG

Aktuelle Seite: HSG/Fächer/Informatik/Material

Algorithmus-Test, objektorientiert

Pflichtenheft

Algorithmen und ihr Test nehmen einen breiten Raum in der Informatik ein. Es soll ein typisches Algorithmen-Testprogramm objektorientiert entwickelt werden. Als Beispiel könnte man den Euklidischen Algorithmus wählen. Doch widerspricht nicht schon die Auswahl eines speziellen Algorithmus dem Prinzip der Kapselung von Daten und Methoden?
Es soll also ein Programm zum Testen eines Algorithmus zur Berechnung des ggT erstellt werden.

Prototyp

Die Eingabe wird aus zwei ganzen Zahlen bestehen, die Ausgabe aus einer ganzen Zahl, der Rechenvorgang soll durch einen Button ausgelöst werden.

Objektorientierte Analyse

Der Prototyp spiegelt die Benutzeroberfläche, das GUI wieder. Sie repräsentiert die Views und den Controls des MVC-Konzepts.
Der Model-Teil, das Fachkonzept soll natürlich von der GUI getrennt werden.
Objekte sollen nach Zuständigkeiten ausgewählt werden, die Zuständigkeit für die Berechnung des ggT erhält ein "ggT-Objekt" oGgT, die zugehörige Klasse soll TggT heißen. TggT braucht eigentlich nur den Algorithmus zu kapseln, das wäre eine Klasse ohne Datenfelder. Manchmal kann es aber nützlich sein, wenn das zuständige Objekt die Eingangsdaten behält.
Das Formular-Objekt Form1 wird für Erzeugung und Vernichtung aller anderer Objekte verantwortlich gemacht. Es steht in der Hierarchie höher, es "hat" die anderen Objekte. Mit UMLEd wurde folgendes Klassendiagramm erstellt:


Im Sinne einer integrierten Dokumentation kann man auch die Möglichkeiten von UmlEd (Datei: ggTooP.urd) benutzen, Anmerkungen zu Objekten, Attributen und Methoden zu machen.

Objektorientiertes Design

In dieser Phase erfolgt die Auswahl bzw. der Entwurf der benötigten Algorithmen. Es sei zunächst der Euklidische Algorithmus ausgewählt. Zu einer guten Dokumentation gehört jetzt die Erläuterung des Algorithmus (Struktogramm, Fundstellen usw.).

Als nächstes steht die Auswahl der zu benutzenden Klassenbibliothekenan. Im Beispiel soll die Delphi-VCL benutzt werden. Natürlich setzt diese Benutzung ein Mindestmaß an Vertrautheit voraus, was hier erwartet wird.
Beim "Zusammenschieben" der Benutzeroberfläche in der Delphi-IDE hantiert man bewusst oder unbewusst mit Objekten, deren Klassen in diversen Units bereitgehalten werden. Auch das Hauptformular ist ein Objekt, das bei der Erzeugung einer neuen Anwendung automatisch "da ist". Man muss sich um Erzeugung und Vernichtung dieser ganzen Objekte nicht kümmern, das Delphi-System trifft automatisch die nötigen Vorkehrungen. Teils sieht man das am automatisch erzeugten Code, teils werden im Hintergrund Objektattribute und Referenzen gesetzt ohne dass man das merkt.

Implementierung

Es folgt der Delphi-Quellcode, wobei das Fachkonzept mit der Klasse TggT in der Unit "uGgT.pas", die Benutzeroberfläche in der Unit "uGUI.pas" zu finden ist.

unit uGgt;  { ggT-OOP, mk, 4.2.03 }

interface

type
  TggT = class(TObject)
         private
           Fa,Fb : integer;
         public
           procedure SetA(z : integer);
           procedure SetB(z : integer);
           function GetggT : integer;
         end;

implementation

procedure TggT.SetA(z : integer);
begin
  Fa := z;
end;

procedure TggT.SetB(z : integer);
begin
  Fb := z;
end;

function TggT.GetggT : integer;

  function Euklid(m,n : integer) : integer;
  var
    r : integer;
  begin
    repeat
      r := m mod n;
      if r = 0 then result := n else begin m := n; n := r end;
    until r = 0;
  end;

begin
  result := Euklid(Fa,Fb);
end;

end.

unit uGUI;   { ggT-OOP, mk, 4.2.03 }

interface

uses
  Forms, StdCtrls , sysUtils , Controls, Classes,
  uGgt;                                  { 1. Fachkonzept-Unit einbinden   }

type
  TForm1 = class(TForm)
    eA: TEdit; lA: TLabel; eB: TEdit; lB: TLabel; eGgT: TEdit; lGgT: TLabel;
    bBerechne: TButton;
    procedure bBerechneClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    oGgT  : TggT;                        { 2. Referenzvariable deklarieren }
  public
    { Public declarations }
  end;

var
  Form1 : TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  oGgT := TggT.Create;                     { 3. Objekt erzeugen            }
end;

procedure TForm1.bBerechneClick(Sender: TObject);
var
  a,b,g : integer;
begin
  a := StrToInt(eA.Text); b := StrToInt(eB.Text);

  oGgT.SetA(a); oGgT.SetB(b);               { 4. Objekt vorbereiten        }
  g:= oGgT.GetggT;                          { 5. Anfrage an Objekt stellen }

  eGgT.Text := IntToStr(g);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  oGgT.free;                                { 6. Speicherplatz freigeben   }
end;

end.

Test

Getestet wurde:
a b Ausgabe ggT(a,b)
512 400 16 16
19 23 1 1
24 15 3 3
Der Test mit ausgewählten Zahlenpaaren scheint die korrekte Funktion zu bestätigen. Doch was passiert für negative Eingaben, für die Eingabe 0, für sehr große, für unsinnige Eingaben? Was sollten man alles testen, bis man zufrieden ist?