Rolf B: Frage bzgl. OOP und einem Klassen Diagramm

Beitrag lesen

Hallo ebody,

ich hätte einen Haufen Anmerkungen

Welches Modellierungstool, bzw. welche graphische Modellierungssprache ist das? In meinem UML Vokabular kommt ein ausgefüllter Pfeil im Klassendiagramm nicht vor.

In welcher Beziehung steht ListSheetData zu ReadSheet? Ist das eine Assoziation? Eine Subklasse?

Wenn es eine Assoziation ist - wie navigiert man vom einen zum anderen? Da sehe ich kein zugehöriges Property. Wenn ListSheetData ein Rückgabewert einer ReadSheet-Methode ist, kann man das im Modell darstellen? Ein Pfeil gehört da dann nicht hin, soweit ich weiß.

Klassen sollten in ihrem Namen keine Tätigkeit darstellen. Sie repräsentieren Dinge, keine Aufgaben. ReadSheet könnte sein Leben als SheetReader führen, in dem Fall müsste es zum SheetReader aber auf jeden Fall noch eine Klasse DataSheet geben. Ist das dein ListSheetData?

Wichtig ist auf jeden Fall, dass der SheetReader sich nur mit dem Lesen beschäftigt und sonst nichts. "Do One Thing And Do It Right".

Methoden wie sheetCheckUrl und setSheetUrl sind da schon verdächtig. Wenn der SheetReader Anforderungen an die URL hat, die über formale Ansprüche an eine URL hinausgehen (z.B. wenn Du nur URLs akzeptieren willst, die das Präfix https://docs.google.com/spreadsheets haben) bestimmte Hostnamen akzeptieren willst), dann sollte er sie beim Entgegennehmen der URL prüfen und eine Exception werfen, wenn es nicht passt. Eine explizite Check-Methode scheint unpassend. Eine set-Methode aber eigentlich auch, die URL kannst Du auch an den Konstruktor übergeben. Andere Fehler, wie einen Existenzcheck der URL, würde ich an der Stelle lassen, weil sie einen Netzzugriff brauchen und daher asynchron sind. Das führt zu einem HTTP Fehlercode beim Lesen, das ist früh genug. Oder Du erstellst eine checkExists Methode, wenn Du wirklich nicht mehr tun willst als die Existenz zu testen.

Die normalen Anforderungen an die URL sollten aber durch die URL-Klasse geprüft werden, die der Browser (außer Internet Explorer) mitbringt. Wenn Du den IE unterstützen willst, musst Du Dir einen URL-Polyfill suchen - aber ich würde die URL Validierung aus dem Reader heraushalten.

Methoden wie countRows() und countCols() sollten demnach Propertys des DataSheet sein, und die SheetUrl sollte der Reader per Konstruktor bekommen. Ist sie falsch - wie gesagt: Exception.

countRows und countCols sind ebenfalls falsch benannt. „count“ sieht hier nach einem Verb aus, und ein Verb gehört zu einer Methode. Aber das sind augenscheinlich keine Methoden, sondern Property-Getter, die den Wert liefern, und demnach sollten sie rowCount und columnCount heißen.

Ein Getter namens transformSheet scheint mir auch verdächtig. Er sollte transformedSheet heißen, wenn er das transformierte Sheet liefert. Alternativ müsste es eine Methode transformSheet() sein, die die Transformation ausführt.

Frage: Wie löst Du die Asynchronität des Lesevorgangs? Ein Datenzugriff über eine URL dauert eine Weile, das ist in JS prinzipiell asynchron.

Wenn ich das baute, würde ich eine read-Methode vorsehen, die ein Promise zurückliefert, so dass man als Anwender dies tun kann:

new SheetReader("http://example.com/somesheet")
.read()
.then(sheet => {
   // sheet verarbeiten
})
.catch(err => {
   // Fehlerbehandlung
});

oder mit neuerer JavaScript Syntax, in einer async Funktion:

try {
   let sheet = await new SheetReader("...").read();
   // sheet verarbeiten
}
catch(err) {
   // handle error
}

Innerhalb von read() kannst Du das mit dem fetch-API implementieren, das ist ohnehin schon Promise-basierend, oder Du kapselst den XmlHttpRequest selbst in ein Promise. Ach, IE. Da bräuchtest Du dann auch einen Polyfill für Promises. Oder Du verzichtest auf IE User, wenn Du Dir das erlauben kannst.

Rolf

--
sumpsi - posui - obstruxi