Simple GUI
-
Hallo,
ich habe eine Anfängerfrage zum Softwaredesign von Oberflächen in C++ (hatte leider im Elektrotechnik-Studium keine Vorlesung dazu).
Was ist "best practice", wenn man kleine GUI Anwendungen objektorientiert schreiben will?Am Besten, ich erläutere mein Problem anhand eines Beispiels.
Ein TCP-Socket soll Daten senden und empfangen und ein Fenster soll diese Daten anzeigen, verarbeiten und senden.
In den Lehrbüchern wird immer der ganze Code in eine einzige Klasse gepackt. Aber sooo winzig soll mein Programm auch nicht werdenFolgendes Problem tritt in meinem Beispiel auf:
myTCPSocket hat keinen Zugriff auf die Methoden und Members von myWindow und umgekehrt. So soll es ja auch sein, Stichwort Kapselung.Jetzt fallen mir verschiedene Möglichkeiten ein, wie man damit umgehen kann:
- friend-Klassen (Nachteil: Kapselung geht verloren)
- static Methoden und static Members (Nachteil: Instanzen der selben Klasse können keine verschiedenen Variablen-Werte speichern)Was ist also die beste Vorgehensweise (best practice), wann man, sagen wir mal ein Programm mit zehn Klassen schreiben möchte?
//****************************************************************************************** //* Filename: App.h * //****************************************************************************************** #include <appLib> //eine willkürliche Lib #include "App.h" #include "myTcpSocket.h" #include "myWindow.h" class App : public appLib{ public: int func_A(int); myTcpSocket* pSocket; myWindow* pWindow; };
//****************************************************************************************** //* Filename: myTcpSocket.h * //****************************************************************************************** #include <tcpSocketLib> //eine willkürliche Lib #include "myTcpSocket.h" class myTcpSocket : public tcpSocketLib{ public: int func_B(int); int data; };
//****************************************************************************************** //* Filename: myWindow.h * //****************************************************************************************** #include <windowLib> //eine willkürliche Lib #include "myWindow.h" class myWindow : public windowLib{ public: int func_C(int); int data; };
-
Ich rate Dir, mach das ganze in C# und verwende Methoden und Events....
Mach also ein Klasse mit der TCP-Kommunikation; diese stellt Methoden und Events zur Verfügung. Jetzt kann z.B. die Oberfläche diese Klasse instanziieren und die Methode aufrufen oder sich auf Events registrieren und eben entsprechend reagieren.
Somit ist die TCP-Kommunikation komplett von der Oberfläche getrennt und muss nix darüber wissen...
-
Und so ein Tipp im c-plusplus-Forum
Werde es wohl so ähnlich machen, allerdings mit C++ und der Qt Bibliothek. Da heißen die Events dann "Signals".Aber interessehalber, wie würde man es in C++ machen?
-
Siehe:
http://www.codeproject.com/Articles/6614/Generic-Observer-Pattern-and-Events-in-CAuch bietet boost signals an:
http://www.boost.org/doc/libs/1_52_0/doc/html/signals.html
-
C.A.B. schrieb:
Folgendes Problem tritt in meinem Beispiel auf:
myTCPSocket hat keinen Zugriff auf die Methoden und Members von myWindow und umgekehrt. So soll es ja auch sein, Stichwort Kapselung.Jetzt fallen mir verschiedene Möglichkeiten ein, wie man damit umgehen kann:
- friend-Klassen (Nachteil: Kapselung geht verloren)
- static Methoden und static Members (Nachteil: Instanzen der selben Klasse können keine verschiedenen Variablen-Werte speichern)Man könnte eine Instanz der Socket-Klasse in der Windows-Klasse verwalten. Somit kann aus einem Objekt der Windowsklasse der Socket benutzt werden. Sollte diese wiederum die (public)-Methoden des Windows benutzen können/müssen, könnte man der Socketklasse einen Zeiger auf 'ihr' Window spendieren.
-
Sehr schlechtes Design; das erzeugt Zyklische Abhängigkeiten, was später sehr schwer zu pflegen ist. Und falls man später man anstelle einer WinAPI-GUI eine andere andocken will, so ist das so gut wie unmöglich....
Also besser: Separation of concerns
-
Vielen Dank für die Anregungen. Ich denke nun, dass Events bzw. Signal/Slots die beste Lösung für mich ist. Also kein nacktes C++.
Und da man damit ebenfalls Daten übergeben kann, benötigt man auch keine globalen Variablen mehr.
-
Zu signals & slots ein Tipp: https://github.com/pbhogan/Signals
-
Du könntest deine GUI in C# dann in einer COM componente packen und dann in C++ nutzen ^^