Guter Stil oder Overhead?
-
Warum erhöht es die Abhängigkeit zwischen Komponenten, wenn ich eine toUpper-Methode in eine String-Klasse stecke? Warum sollte ich weniger Abhängigkeiten haben, wenn ich eine freie Funktion toUpper(string) habe?
Das geht am Punkt vorbei, toUpper ist nichts, was ich persönlich aus den von mir genannten Erwägungen in eine eigene Komponente verladen würde.
Abgesehen davon sind freie Funktionen im OOA eh nicht wirklich präsent.Aber unabhängig von der Operatorüberladung, im Allgemeinen ist das eine Gratwanderung:
Auf der einen Seite ist das "Minimalinterface", eine ausgesprochen hässliche Lösung: Getter und Setter für alle Interna, der Rest wird über "Manipulator"-Komponenten gelöst. Das ist Quatsch und trägt nichts zur Auflösung von Abhängigkeiten bei, sondern stellt eben gerade neue (zwischen Komponente und Manipulator) her (hohe Kohäsion innerhalb der Komponenten, aber leider auch starke Kopplung).
Auf der anderen dagegen das Monolith-Antipattern: Eine Komponente ist für alle Operationen verantwortlich, die mit ihr zu tun haben (sehr niedrige Kohäsion, dafür kaum Kopplung). Man muss nur in den richtigen Momenten den richtigen Weg wählen, um beide Maße an ihr Optimum anzunähern.Ein Beispiel: Das Visitor-pattern. Im simplen Fall von Binärbaumtraversierungen wird die Motivation schon sichtbar: Es ist nicht Aufgabe eines Binärbaums, sich selbst Pre-, Post- oder Inorder zu durchlaufen. Das ist Logik, die man außerhalb der Datenverwaltung (dem Baum) unterbringen möchte. Das erhöht die Kopplung zwar, verringert aber auch die Kohäsion. Ob und wie sehr sich das lohnt muss man im Einzellfall entscheiden.
-
JFB schrieb:
Warum erhöht es die Abhängigkeit zwischen Komponenten, wenn ich eine toUpper-Methode in eine String-Klasse stecke? Warum sollte ich weniger Abhängigkeiten haben, wenn ich eine freie Funktion toUpper(string) habe?
Das geht am Punkt vorbei, toUpper ist nichts, was ich persönlich aus den von mir genannten Erwägungen in eine eigene Komponente verladen würde.
Abgesehen davon sind freie Funktionen im OOA eh nicht wirklich präsent.Naja, das war der Punkt, aber sonst kann ich dir zustimmen.
-
Im Falle der operatoren ist nicht nur Kapselung sondern auch Symmetrie ein Thema.
Ista == b
etwas komplett anderes alsb == a
? Nicht, oder? Beide sind gleichwertig, deshalb sollte der operator== dies auch ausdrücken, und nicht an irgend ein einzelanes Objekt gebunden sein.
-
hmmmm schrieb:
Warum erhöht es die Abhängigkeit zwischen Komponenten, wenn ich eine toUpper-Methode in eine String-Klasse stecke? Warum sollte ich weniger Abhängigkeiten haben, wenn ich eine freie Funktion toUpper(string) habe?
Du hast
toUpper
von der Stringklasse entkoppelt und kannst Spezialisierungen fuer andere Stringklassen anbieten, ja selbst fuerstd::vector<char>
std::array<char, 15>
oderchar
-Arrays, die selbst keine Klassen sind. Und mit Templates musst dutoUpper
wahrscheinlich nur einmal implementieren.
-
Etwas ausführlicher:
Dr Dobbs: How Non-Member Functions Improve Encapsulation
-
knivil schrieb:
hmmmm schrieb:
Warum erhöht es die Abhängigkeit zwischen Komponenten, wenn ich eine toUpper-Methode in eine String-Klasse stecke? Warum sollte ich weniger Abhängigkeiten haben, wenn ich eine freie Funktion toUpper(string) habe?
Du hast
toUpper
von der Stringklasse entkoppelt und kannst Spezialisierungen fuer andere Stringklassen anbieten, ja selbst fuerstd::vector<char>
std::array<char, 15>
oderchar
-Arrays, die selbst keine Klassen sind. Und mit Templates musst dutoUpper
wahrscheinlich nur einmal implementieren.Wie frage ich
std::vector<char>
nochmal nach seinem Encoding?
-
Wie fragst du denn std::string?
-
Ja, toUpper funktioniert hier nur, wenn man Information-Hidding verletzt und annimmt, man weiß wie der String seine Daten intern hält.
-
Irgendwie verstehe ich nicht, worauf du gerade hinaus willst.
-
hmmmm schrieb:
Wie frage ich
std::vector<char>
nochmal nach seinem Encoding?Gar nicht. Die Unterstuetzung fuer Utf in C++ ist nicht besonders gut. Aber deswegen kannst du trotzdem eine Klasse
UtfString
definieren undtoUpper
dafuer spezialisieren, die das Encoding abfragt.Ja, toUpper funktioniert hier nur, wenn man Information-Hidding verletzt und annimmt, man weiß wie der String seine Daten intern hält
Wie du siehst, kann das am Typ festgemacht werden. Und warum sollte ich den verstecken?
-
ist glaub ich sinnlos weietr zu machen.
-
hmmmm schrieb:
Ja, toUpper funktioniert hier nur, wenn man Information-Hidding verletzt und annimmt, man weiß wie der String seine Daten intern hält.
ähh...nein? Iteratoren?
-
ähh...nein! Encoding weiterhin undefiniert.
Utf8String Utf16String Utf32String kommen gleich vorbei...
-
aber das Encoding kennt std::string ja selbst nicht. Ich würde ja jetzt sagen: "locale fragen" aber das geht nicht, wenn du UTF8-kodierst. std::string ist nicht für variable-breite zeichen ausgelegt. UTF-32 (mit unsigned int als char_t) würde aber gehen. Also: richtigen Stringtyp verwenden und dann locale fragen(und facets implementieren). Oder auf wchar_t hoffen und locale fragen. Unter Unixoiden funktioniert das sogar.
-
Ist es nicht offensichtlich, welches Encoding verwendet wird?
ASCII ist ein Subset von UTF-8, also kann man wohl bei jedem 8bit-string annehmen, dass er UTF-8 kodiert ist.
Bei einem 16bit-Typen gehe ich von UTF-16 aus, analog dazu von UTF-32 bei 32bit.Ein Denkfehler dabei?
-
Ja, das 8Bit eben nicht UTF-8 bedeutet. Es kann auch zum Beispiel ein beliebiger erweiterter ASCII sein wie unter einigen Systemen üblich. Es muss nicht einmal ASCII kompatibel sein.