-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
API is too unflexible/non-OOPish #1
Comments
More input please. Bitmap24 btw is not a conventional canvas, but rather a buffer. Since all drawing operations implement IBatchDrawable (it should have been IDrawable, but that would require black voodoo), a list of IBatchDrawable* describes the operations on an empty canvas. These later will be applied to a concrete buffer (picture), that is, a (Batch)Bitmap24. This is why all of these classes shall use RelativeCoordinates. You're right if you mean some of the member functions should have been Operations like rotating or mirroring the picture have not been part of the requirements I made up for the drawing program. In fact, they currently work if they act inside the fixed-size "canvas" (the buffer of the bitmap). Anything else would require additional logic like a variable-sized buffer (remember: the bitmap has alignment issues in the rows). Please consider simplicity as a main aspect here. |
Of course it is. A simple transformation layer acting as a proxy between |
Warum egtl. auf eng? Würde das nicht wieder erfordern, das Wenn ich dich richtig verstehe, soll das Bild sich (die Koordinaten, nicht der Speicherinhalt) drehen können, damit Bresenham besser zu implementieren ist? |
Keine Ahnung. Warum hast du eine Maske auf? Und bist nicht im Chat?
Das ist so shice egal. In dem Workshop geht es nicht darum, wie man den Code so hinbiegt, dass $Compiler den gut verdauen kann. Und noch weniger bei der Einführung ins Thema OOP. Wenn der Code 25% langsamer ist: Who cares? Für unseren Anwendungszweck ist es egal.
Nicht das Bild. Ein Proxy der vor das Bild geschaltet wird. Es ist nicht die Aufgabe des Bildes, Koordinatentransformationen durchzuführen. Dafür gibt es das Proxy-Pattern. Damit könnten zum Beispiel Achsen vertauscht oder skaliert (für Bresenham mit +-1) werden. Nachtrag: Die Aufruf-Sequenz wäre dann wie folgend gewesen: Kern des Problems ist: Du hast Annahmen darüber gemacht, wie andere die API benutzen. Tatsächlich sollte die API so universell einsetzbar sein wie möglich und dementsprechend möglichst wenige Annahmen über die Verwendung treffen. |
Ich sehe aber den Punkt denke ich, und über den Aspekt "tradeoff guter Stil vs. gute Performance" habe ich auch nachgedacht. Hier lässt sich definitiv noch diskutieren. Eigentlich geht es imho aber um die Definition der Anforderungen als um das Interface selbst. Wenn in den Anforderungen nicht enthalten ist, dass das Bild z.B. Drehungen vollziehen kann, dann ist bspw. ein fester Puffer möglich.
Andere Sichtweisen:
Es kann gut sein (auch wenn ich für eine präzisere Antwort mehr Bibliotheken kennen müsste), dass die Verwendung eines root-Interfaces in rein objektorientierten Sprachen wie Java und C# geläufiger ist, hingegen in C++ weniger (abgesehen von Undingen wie qt). Dass in C++ häufig besser mit einem root-Interface gearbeitet werden sollte, möchte ich dabei nicht in Abrede stellen. Es scheint mir nur bereits auf sprachlicher Ebene eher der Fall zu sein, dass C++ weniger eine streng Paradigmen-orientierte Sprache ist als eine Sprache, die sich sowohl an Paradigmen als auch an der Implementierung orientiert. Bei der ganzen Geschichte hatte ich zwei Aussagen im Hinterkopf: Die eine stammt von Alexander Stepanov (Erfinder des generischen Programmierens und der STL) die andere von Günter Quast (Prof. am EKP, arbeitet an der Datenanalyse von LHC-Experimenten mit). Beide sagen ungefähr, dass totale Objektorientierung an der Wirklichkeit vorbeigeht. Das ist mit dem Hintergrund zu sehen, dass bei größeren Frameworks mit großer Hierarchie viel Laufzeit für die Objektorientierungs-Mechanismen draufgeht (laut Quast). Das kann natürlich nur bedingt ein Argument sein, bei einer Vorstellung von Objektorientierung nur halbherzig objektorientiert zu arbeiten. Viel eher hatte ich dabei die Einfachheit im Hinterkopf, dass also nicht zu viel Flexibilität den Einblick in die Funktionsweise oder die Einfachheit der Verwendung verhindert. Daher habe ich an die höchste Stelle der Hierarchie eine möglichst einfache, grundlegende Klasse gestellt, die gerade soviel Implementierung bietet, dass sie nach außen hin sicher ist (zunächst war das Ding nur da zum Abspeichern, aber da möglicherweise BatchBitmap24 von den TNs hätte implementiert werden sollen, mussten die restlichen Teile wie getter/setter noch dran). Momentan vertrete ich folgende Meinung: Das "Interface" (Bitmap24) ist flexibel genug für alles, was mit dem Zeichenprogramm getan werden soll (möglicherweise bis auf den Fakt, dass Die in der Wirklichkeit verwendete Variante hat denke ich Sven (? Oli?) schon genannt: Eine Canvas-Klassenhierarchie, bei der die Canvas-Implementierung die Primitives anbietet. Das Performance-Problem tritt dann in den Hintergrund, wenn die "internen" (virtuellen) Methoden selbst gewisse Komplexität erreichen. Das ist aber hier bei |
Möglich. Aber nicht nötig. Beim Interface-Design liegt der Tradeoff darin, es so flexibel und unbeschränkt wie möglich zu entwerfen, ohne dass dabei die Komplexität überhand nimmt.
Das sind Sonderfälle. Ich fordere auch nicht die totale Objektorientierung (wer wollte noch eine Funktion zum Zeichnen von Linien als Objekt?) sondern mit Augenmaß. Und Fakt ist, dass Code mit schlechter Architektur und schlechter Umsetzung den größten Teil des Wartungsaufwandes bei Softwareprojekten ausmacht. (Und damit, um die Welt jenseits des Elfenbeinturms zu berücksichtigen: Auch der Kosten)
Es ist in diesem Kontext überhaupt kein brauchbares Argument. Gerade da sollte man eigentlich vorbildlich Arbeiten.
Schlechte Nachricht: Das ist dir nur zum Teil gelungen. Ich weiß aus dem Channel, dass mindestens eine Person im Praxisteil daran verzweifelt ist, nachzuvollziehen was du von ihr willst und wie die API dazu genutzt werden soll. |
A good API design would consist of an interface as root, allowing to build wrapper-classes around Bitmap24. (Example: For on-the-fly dimension-flipping)
The text was updated successfully, but these errors were encountered: