Wrapper für Bibliotheken oder direkt benutzen?



  • Benutzt ihr Bibliotheken direkt oder schreibt ihr euch Wrapper dafür?

    Beispiel:
    Ich will ein Fenster aufmachen und dort Text reinschreiben.
    Mein Vorgehen wäre: Ich baue mir Funktionen und Klassen die genau tun was ich will und nehme dann, sagen wir mal die WinAPI, und implementiere sie damit:

    //c++-artiger Pseudocode
    //meine wunschfunktionen
    class fenster{
        fenster(); //fenster komplett fertig bauen mit allem drum und dran
        schreibeTextRein(const char *text); //text reinschreiben (und automatisch anzeigen)
        ...
    };
    //irgendwie implementierte wunschfunktionen
    fenster::fenster(){
        hauptfenster = CreateWindow( ... );
        textfenster = CreateWindow("STATIC", ...);
        ...
    }
    fenster::schreibeTextRein(const char *text){
        SendMessage(textfenster, WM_SETTEXT, 0, (LPARAM)text);
    }
    //meine programmlogik
    int main(){
        fenster = new fenster();
        fenster->schreibeTextRein("Hello World!");
        ...
    }
    

    Irgendwie finde ich es logisch so.
    Mir ist aber aufgefallen, dass ich scheinbar der einzige bin der das so macht. In jedem Tutorial und Beispielcode werden die Funktionen einfach direkt aufgerufen und fertig, ohne fensterklasse und ohne schreibeTextRein-Funktion.

    Ich fand meine Variante immer vorteilhaft, weil ich zum Beispiel die WinAPI-Funktionen mal eben durch GTK-Funktionen ersetzen kann und schon läufts unter Linux, die Programmlogik bleibt erhalten. Wenn man die Funktionen direkt benutzt ist das viel komplizierter, da man sich normalerweise an die WinAPI-Logik hält und zum Beispiel eine WinMain hat, um dann festzustellen, dass das scheinbare Äquivalent gtk_main etwas völlig anderes tut und man das halbe Programm umschreiben muss.

    Das ist allerdings auch schon schief gegangen, meine starteThread(funktion, Argument1, Argument2, ...) - Funktion die ich von Python kenne habe ich nie in C implementieren können (man kann die Ellipse nicht auflösen), sodass ich schließlich die Programmlogik der Threadbibliothek anpassen musste, was mir überhaupt nicht gepasst hat.

    Was sind eure Erfahrungen damit? Haben Wrapper zuviel Overhead? Zuviel unnötiger Code? Sollte man sich lieber die Bibliotheken ordentlich ansehen statt auf einfachen Bibliothekswechsel zu achten?

    Ich würde mich über einige Einschätzungen, Erfahrungen und Meinungen freuen.



  • Ich würde sagen das kommt drauf an 😃



  • nwp2 schrieb:

    Ich fand meine Variante immer vorteilhaft, weil ich zum Beispiel die WinAPI-Funktionen mal eben durch GTK-Funktionen ersetzen kann und schon läufts unter Linux, die Programmlogik bleibt erhalten. Wenn man die Funktionen direkt benutzt ist das viel komplizierter [...]

    Genau das ist der grosse Vorteil davon. Die Frage ist aber, ob man das immer braucht? Wenn man bei der WinAPI bleibt, muss man ja nicht unbedingt davon abstrahieren.

    Dennoch sind Wrapper bei C-APIs oder allgemein Low-Level-Bibliotheken praktisch, vor allem, wenn man gewisse Dinge dauernd wieder braucht, die mühsam direkt zu erledigen sind. Auch kann man so schön Speicherverwaltung und andere Dinge automatisieren und eine Kapselung aufbauen.

    Jede Bibliothek zu wrappen, bevor man sie einsetzt fände ich jetzt aber arg übertrieben. Manchmal gewinnt man wirklich nicht viel, und wenn der Adapter dann auf eine reine Änderung der Namenskonvention hinausläuft, kann mans auch lassen. 😉
    Ich meine, es gibt ja auch viele High-Level-Bibliotheken, die man direkt einsetzen kann. Z.B. grosse Teile von Boost. Oder von SFML. Die sind halt oft selbst in C++ geschrieben, und bieten bereits spezifische Funktionalität fertig an. Da kann man zwar immer noch eine Zwischenschicht einlegen, aber je nachdem bringt das nur wenig.

    Zusammengefasst meine ich, es ist von Fall zu Fall unterschiedlich, ob und in welchem Mass Wrapperklassen und -funktionen sinnvoll sind. Entscheidende Faktoren können sein:

    • Unterschiede zwischen Abstraktionslevel der Bibliothek und des Anwendercodes
    • Wichtigkeit von Wiederverwendung und Portierbarkeit
    • Notwendigkeit von Automatisierung und Verbergung technischer Details (Ressourcenmanagement etc.)
    • Aufwand, Zeitverbrauch


  • evtl. könnte man als kontra die einarbeitungs zeit eines neuen entwicklers aufführen, denn der kennt deine wrapper klassen mit an sicherheit grenzender wahrscheinlichkeit nicht. aber evtl. kennt er sich schon ein bischen mit winapi, sdl, qt oder ähnlichen librarys aus. und kommt somit schneller in nen workflow.

    lg lolo



  • Wrapper haben einen Nachteil: du musst einen gemeinsamen Nenner finden und kannst spezielle Funktionen nicht nutzen



  • nwp2 schrieb:

    Ich fand meine Variante immer vorteilhaft, weil ich zum Beispiel die WinAPI-Funktionen mal eben durch GTK-Funktionen ersetzen kann und schon läufts unter Linux, die Programmlogik bleibt erhalten.

    Programmlogik und GUI sollten voneinander getrennt sein. Siehe MVP (http://de.wikipedia.org/wiki/Model_View_Controller)

    Ansonsten macht ein solcher Mehraufwand nur dann Sinn wenn es tatsächlich die Notwendigkeit gibt portabel zu sein. Es nur zu machen weil man es brauchen "könnte" ist einfach kein guter Grund.


Anmelden zum Antworten