MB: Class Diagram - Übergabemodus bei Operation verstehen

moin,

den übergabemodus in, out und inout habe ich nicht so richtig verstanden. Ich hab aber ne Ahnung und benötige Bestätigung ob das sooo korrekt ist.

UML Class Diagram Operation Parameter Syntax:
[visibility] name ([Parameter-List]) [:return value] [multiplicity] [{property}]

IN
UML Class Diagram Operation: +setFoo(in foo :float ) :void
PHP: public function setFoo( float $foo ) { $this->foo }

OUT
UML Class Diagram Operation: +getFoo( out ) :float
PHP: public function getFoo() { return $this->foo }

INOUT
UML Class Diagram Operation: +calcBar(inout bar :float ) :void
PHP: public function calcBar( float $bar ) { return $bar * 2 }

ich hoffe auf bestätigung obwohl ich mit in dem letzten Punkt inout über die Sinnigkeit nicht ganz im klaren bin 😕. Heißt der Präfix des Operations Parameters nur, das der Parameter in dieser Funktion (hier:calcBar) verändert und wieder zurück gegeben wird? Ich kann mir diesen Präfix anders nicht vorstellen.

Zum Beispiel public function calcBar( float $bar ) { return $bar } wäre der Parameter unverändert aber mit dem Präfix inout konform?

Ich freue mich auf fachkenntnisse 😀!

lgmb

--
Sprachstörung
  1. Hallo MB,

    ich bin kein UML Papst, aber +getFoo( out ) :float kann eigentlich keinen Sinn ergeben. in/out/inout geben an, welchen Weg die Daten bei diesem Parameter nehmen.

    in: Der Aufrufer übergibt der Funktion einen float Wert. out: Die Funktion hinterlegt hier für die Funktion einen Wert inout: Der Aufrufer übergibt einen Wert und die Funktion kann ihn ändern.

    Die Angabe hinter der schließenden Klammer gibt an, welchen Typ der Rückgabewert der Funktion hat.

    in

    UML: doSomething(in foo: float) : int
    PHP: function doSomething($foo: float) : int { return 4711; }

    Beachte: PHP kennt mittlerweile ebenfalls Typdeklarationen für die Rückgabe.

    out

    UML: doSomething(out foo: float) : int

    Diese Funktion gibt zwei Werte zurück. Einen int-Wert als normalen return-Wert, und einen float-Wert im out-Parameter foo. Dafür muss sie diesem Parameter einen Wert zuweisen. Einen Wert in die Funktion hineingeben kannst Du mit dieser Aufrufkonvention nicht. In Sprachen wie C# gibt's sogar einen Compile-Fehler, wenn eine Funktion einem out-Parameter nichts zuweist.

    PHP: Es gibt kein reinen out-Parameter. Nur inout. Auch „Referenzen“ genannt.

    inout

    UML: doSomething(inout foo: float) : int

    Diese Funktion gibt ebenfalls zwei Werte zurück. Einen int-Wert als normalen return-Wert, und einen float-Wert im out-Parameter foo. Der Unterschied zur vorigen Signatur ist, dass die Funktion in foo auch noch einen Wert entgegennimmt. In PHP löst man das mit einem Referenzparameter, erkennbar am & vor dem $ in der Funktionsdeklaration. Aber nur dort, nicht beim Aufruf. Eine typische PHP Methode, sich in den Fuß zu schießen! Das ist in anderen Sprache anders, da muss man den call-by-reference auf beiden Seiten festlegen. Damit man beim Aufruf und in der Funktion sieht, dass das passiert.

    Angesichts dieser Syntaxschwäche sollte man inout nach Möglichkeit meiden und nur Rückgabewerte nutzen. Man kann zur Not ein Array mit mehreren Werten darin zurückgeben.

    Syntaxbeispiel in PHP:

    function doSomething(&$foo) : int {
       $foo *= 42;
       return intvaö($foo / 1000);
    }
    
    $a = 4711;
    $milliA = doSomething($a);
    // $a ist jetzt 197862, und $milliA ist 197
    

    Aber ich würde das nicht tun. Wenn man zwei Werte zurückgeben will, dann tut man das auch. Dafür gibt's Arrays und den list-Operator. Es mag einen Tick langsamer sein. Aber dafür massiv lesbarer.

    function doSomething($foo) : array {
       $bar = $foo * 42;
       return ARRAY($bar, $bar / 1000);
    }
    
    $a = 4711;
    list($a, $milliA) = doSomething($a);
    

    Du kannst, wenn Du Bedarf an einem out-Parameter zu haben glaubst, ihn in PHP mit einem Referenzparameter implementieren. An dieser Stelle ist es tatsächlich interessant, kein Array zurückzugeben. Nimm an, du hättest eine Funktion, die einen String in eine Zahl konvertiert, aber nur, wenn es auch wirklich eine ist. Hier braucht man zwei Ergebnisse: die geparste Zahl, und ein Flag, ob das Parsing möglich war. In C# heißt diese Funktion tryParseInt. Wenn das Ergebnis ein out-Parameter ist und das Erfolgs-Flag ein bool-return, kann man das so verwenden:

    if (tryParseInt($string, $result)) {
       // tu was mit $result
    }
    

    und das ist praktischer, als ein Array zurückzugeben. Wenn die Syntax denn klarer wäre. In C# schreibe ich:

    if (int.tryParse(stringValue, out result)) {
       // tu was mit $result
    }
    

    und da sieht man direkt, dass ein Wert zurückkommt.

    Rolf

    --
    sumpsi - posui - obstruxi