Untersch. Bib-Aufrufe -> Wie sauber schreiben?



  • Hallo,

    ich möchte 2 unterschiedliche Bibliotheken verwenden in meinem Algorithmus. Ich will aber sauber bleiben und möglichst vielleicht nur eine schnittstelle aus dem Algorithmus anbieten. Das Problem ist dass beide unterschiedliche Parameter brauchen. Ich will aber keinesfalls den code duplizieren.

    Darf/Sollte die Signatur eine vereinigung aller parameter sein und in den unterschiedlichen funktionen dann einige parameter einfach nicht verwendet werden?

    Und wohin schreibt man so Aufrufe der Class::Bib_Call() ? Wie macht ihr das?

    Ginge vielleicht irgendwie sowas?

    //...irgendwo im Algorithmus
    A = Bib_Call(a,b,c,d);
    
    //da wo die Bib-Funktionen separat aufgerufen werden - wo sollte dies sein?
    int Class::Bib_Call(int a, double b, char c, int* d)
    {
         return lib_call_bib1(a,c);
    }
    
    //und da wo die andere lib ist
    int Class2::Bib_Call(int a, double b, char c, int* d)
    {
        return lib_call_bib2(b,d);
    }
    


  • Das kann man so abstrakt nicht sagen, weils Situationsabhängig ist. Meistens ists aber nicht unbedingt sinnvoll, überflüssige Parameter zu haben. Gib uns mal das konkrete Problem, vor dem du stehst.



  • naja ist ein wenig schwierig weil ich ja eben dabei bin das Problem umzusetzen.

    Das kann man so abstrakt nicht sagen, weils Situationsabhängig ist.

    ich versteh leider nicht genau warum das situationsabhängig ist.

    Ich versuche vielleicht ein anderes konkretes Beispiel:

    Angenommen ich habe eine Matrix und einen Vektor in separaten Arrays:

    int** matrix;
    int* vec;
    

    Und ich will jetzt eine Matrix-Vektor-Multiplikation ausführen. Ich habe 2 Bibliotheken (bib1, bib2) und beide implementieren diese Multiplikation anders.
    Je nach input-flag will ich jetzt entweder die Multiplikation über bib1 und eben über bib2.
    Da ich aber mehrere solche Aufrufe habe dachte ich eine Regelung über if-Abfragen im Haupt-code ist unsauber bzw. nicht gerade übersichtlich.

    Deswegen wollte ich eine gemeinsame Schnittstelle haben über Class::Bib_Call().
    Vielleicht ist das Blödsinn keine Ahnung.
    Aber angenommen es käme mal eine dritte Bib hinzu - da jetzt jede if-abfrage zu erweitern ist doch nicht gerade sinnvoller weg oder?

    Besser verständlich?



  • bei deinem matrix-vector Beispiel sehe ich nicht wie da die bibcalls mit verschiedenen parametern zustande kommen sollen. Das Beispiel würde ich wie folgt lösen:

    - Schaffe eine abstrakte Basisklasse die die Routinen deklariert die du brauchst, und zwar für die Klassen die du geschrieben hast.

    struct AbstractMatrixMultiplicator
    {
      MyMatrix multiply(MyMatrix const& lhs, MyVector const& rhs) = 0;
    };
    

    - Für die verschiedenen Libs die zum Einsatz kommen könnten, definierst du jeweils eine Klasse, die von der abstrakten klasse ableitet und die Routinen implementiert, und zwar so, dass sie die von dir definierten Klassen übersetzen in das, was die Bibliotheken eben grade brauchen, dann die Bibliothek aufrufen, und am Ende das von der Bibliothek gelieferte Ergebnis wieder zurückübersetzen.



  • hmm...und wie instantiiere ich dann abhängig von einem flag das ich dem programm übergebe?

    müssen die methoden in der basisklasse nicht virtual sein?



  • testo schrieb:

    hmm...und wie instantiiere ich dann abhängig von einem flag das ich dem programm übergebe?

    Über eine Fabrik oder Fabrikmethode:

    enum Lib{ XYZLib, ABCLib }
    
    AbstractMatrixMultiplicator* getMatrixMultiplicator(Lib lib)
    {
      switch (lib)
      {
        case XYZLib: return new XYZMatrixMultiplicator;
        case ABCLib: return new ABCMatrixMultiplicator;
        default: throw UnknownLibraryException;
      }
    }
    

    gogle mal nach factory pattern und factory method pattern. Oder besorg dir das GOF-Buch, ist eigentlich ein Muss für jeden der etwas mehr als nur "hello world!" schreiben möchte:
    Entwurfsmuster | ISBN: 3827328241

    müssen die methoden in der basisklasse nicht virtual sein?

    Ja sorry, natürlich.



  • erstmal danke

    und zwar so, dass sie die von dir definierten Klassen übersetzen in das, was die Bibliotheken eben grade brauchen,

    hmm...aber wie soll das gehen? Abstrakte Methode und Implementierung in den jeweiligen Klassen müssen doch dieselbe signatur haben...wie meinst Du das? Kleines Beispiel? 🙂



  • MyMatrix XYZMatrixManipulator::multiply(MyMatrix const& lhs, MyVector const& rhs)
    {
      XYZMatrix xm = konvertToXYZMatrix(lhs);
      XYZVector xv = konvertToXYZVector(rhs);
      XYZMatrix xm2 = XYZLib::math::irgendeineMultiplikationsFunktion(xm, xv);
      MyMatrix mm = konvertFROMXYZMatrix(xm2);
      return mm;
    }
    

Log in to reply