Art of Code, Refactoring, Sinn und Unsinn von Funktionen

Gegeben – aus welchem Grund auch immer – sei folgender Code:

function getRights(){
  $arr_rights = array();
  array_push($arr_rights, ‚admin‘);
  array_push($arr_rights, ‚client‘);
  array_push($arr_rights, ’superadmin‘);
  return $arr_rights;
}
function getRights_Superadmin(){
  $zws_rights = array();
  $zws_rights = getRights();
  return $zws_rights[2];
}
function getRights_Admin(){
  $zws_rights = array();
  $zws_rights = getRights();
  return $zws_rights[0];
}
function getRights_Client(){
  $zws_rights = array();
  $zws_rights = getRights();
  return $zws_rights[1];
}

Die Aufrufe der Funktionen getRights_Client(), …Admin() und …Superadmin() kommen im gesamten Script 16 mal vor, insgesamte Laufzeit der Datei, in denen diese Funktionen sind, liegt bei 0,113ms.

1

Folgendes Problem ergibt sich:
Bei jedem Aufruf einer der 3 Funktionen wird jedes Mal die Funktion getRights() aufgerufen, ergo wird diese Funktion 16 mal gerufen und verbraucht damit eine Laufzeit von 0.046ms, allein durch diese 16 Aufrufe.
An dieser Stelle – mal abgesehen davon dass es einfach “bad style” und ziemlich unoptimiert ist – sollte man refactorisieren.

Zuerst muss man den Sinn und Zweck verstehen, also: Was machen die Funktionen und warum?

Was machen die Funktionen?
Die Aufrufe der 3 Funktionen geben den Namen des jeweiligen aktuellen Benutzerrechtes wieder, der Name spiegelt sich in einer Datenbank wieder (ja, auch das hätte man anders machen können und sollen, aber dafür bleibt bei einer Bearbeitung von bestehendem Code nicht soviel Zeit) und diese Namen müssen auch 1:1 übernommen werden, will Mensch nicht den ganzen Code ändern (wozu Mensch normalerweise keine Zeit hat).

Welchen Sinn hat das ganze?
Die Funktion wie Sie oben stehen haben schon einen – wie ich meine – akademischen Sinn. Ziel des ganzen war es bestimmt, die jeweiligen Rechte einmal festzulegen und diese dann, mithilfe der Funktionen, an vielen Stellen abzufragen und zu vergleichen.

Der Weg über Funktionen und immer wieder kehrende Aufrufe anderer Funktionen ist jedoch im besten Falle als unpassend zu bezeichnen. Sicher: Es funktioniert, allerdings sollte ein guter Entwickler auch immer versuchen, seinen Code nicht nur funktional zu tippen, sondern auch “gut” und effizient.
Und effizient ist dieser Code nicht.

Kommen wir also zur Verbesserung: Wir refactorisieren den Code!

Aus Funktion und Sinn kann man leicht ersehen, dass das Mittel der Wahl am besten mit Konstanten umgesetzt werden kann.

Dazu definieren in der Datei im Kopfbereich diese Konstanten:

define(‚RIGHT_CLIENT‘, ‚client‘);
define(‚RIGHT_ADMIN‘, ‚admin‘);
define(‚RIGHT_SUPERADMIN‘, ’superadmin‘);

Nun ändern wir zuerst die Funktion getRights() entsprechend ab:


function getRights() {
  $arr_rights = array();
  array_push($arr_rights,RIGHT_ADMIN);
  array_push($arr_rights,RIGHT_CLIENT);
  array_push($arr_rights,RIGHT_SUPERADMIN);
  return $arr_rights;
}

Und nun können wir in den einzelnen Funktionen die Konstanten ins Spiel bringen.
Dadurch entfallen natürlich auch die Aufrufe von getRights() innerhalb der Funktionen, was eine Entlastung der Aufrufe von getRights() von 8 Aufrufen erbringt:

function getRights_Superadmin() {
  return RIGHT_SUPERADMIN;
}
function getRights_Admin() {
  return RIGHT_ADMIN;
}
function getRights_Client() {
  return RIGHT_CLIENT;
}
Und nun wird wieder profiliert und es ergibt sich folgendes Bild:
2

Nun wird die Funktion getRights() gar nicht mehr aufgerufen (der Aufruf erfolgt aber an anderen Stellen noch, die Ausführzeit nur dieser einen Datei liegt nun bei 0,054ms, also knapp 50% unter der eigentlichen Zeit und die 3 Funktionen haben ebenfalls verkürzte Ausführzeiten.

Die Funktionen selbst sind erhalten geblieben, der “Sinn” auch, denn die Rechte können zentral verwaltet und geändert werden.

Der nächste Schritt wäre, im gesamten Script die Aufrufe von getRight_Client(), …Admin() und Superadmin() gegen die entsprechenden Konstanten zu tauschen, so dass kein Aufruf mehr an diese Datei gehen würde. Dies kann man machen, ohne dabei den “Sinn” oder Funktion zu beeinträchtigen, allerdings fällt das wieder unten den Punkt “Zeit, die einem keiner bezahlt”, aber sinnvoll aus Sicht der Refactorisierung und des “Good styled code” wäre es sicherlich.

Noch am Rande: Alle Profilierungen wurden mit dem Zend Studio 7 vorgenommen, die Screenshots entstammen den jeweiligen Reports der “Execution Statistic”.

Kommentare dazu sind gern gesehen 😉

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.