2010-10-07 4 views
0

Je suis en train de concevoir un serveur qui est utilisé dans la communication UDP en utilisant MFC. Je les classes suivantesMa conception pour le serveur socket UDP est-elle correcte?

  • CMyDlialog - Prenez soin de l'interface utilisateur
  • CController - Agir en tant que médiateur entre toutes les classes
  • CProtocolManager - Prenez soin de codage/décodage msgs (Ceci est une classe statique)
  • CConnectionManager - Prenez soin de connexion UDP, envoi, réception

Je crée un objet de CConnectionManager comme une variable membre dans CController et objet de CController comme variable membre dans CMyDialog.

Lorsque l'utilisateur tape quelque chose et appuie sur envoyer, j'appelle une méthode dans CControler qui appelle une méthode dans CProtocolManager pour construire le paquet et appelle la méthode CConnectionManager pour l'envoyer.

Lorsque je reçois des données, elles sont gérées dans un thread de CConnectionManager. Là je crée un objet local de CController et appelle une méthode, qui passera les données à CProtocolManager pour décoder.

Maintenant, je tiens à informer l'interface utilisateur sur les données, comment devrait le CControler le faire? Je peux poster un message à l'interface utilisateur en rendant le handle de dialogue principal global, est-ce une approche correcte.

Dites-moi également si ce design est correct.

Merci à l'avance

Répondre

0

Je pense que les conceptions ne sont jamais bonnes ou mauvaises, mais vous pouvez les évaluer selon certains principes que beaucoup considèrent comme «bons» (voir the SOLID principles).

Votre approche d'envoi semble raisonnable, mais rendre le Dialog global pour la réception est définitivement considéré comme "pas si bon". Voir the hollywood principle. Je vous suggère de passer une méthode de rappel à votre gestionnaire de connexion qui est une méthode de CController (qui permet ensuite à CProtocolManager de le décoder et d'appeler une autre méthode de rappel depuis la boîte de dialogue). Si callbacks ne sont pas ce que vous voulez, vous pouvez définir AbstractBaseClasses (ABC) comme celui-ci « AbstractMessageReceiver » avec une méthode

virtual void receive(const char*, int length) = 0; 

Vous pouvez ensuite mettre en œuvre cette ABC CProtocolManager passer cela comme un « AbstractMessageReceiver * » à CConnectionManager qui appelle ensuite

m_myMessageReceiver->receive(m_buffer, m_length); 

ou quelque chose de similaire.

Cette approche réduit le couplage, est beaucoup plus testable et augmente la réutilisabilité.

En outre, je suis d'accord avec Am que vous devriez penser à votre modèle de threading!

+0

Donc, je devrais passer le AbstractMessageReceiver * à la fonction de thread qui reçoit les données et passer cela au contrôleur qui appellera la méthode actuelle de recieve? – Jeeva

+0

vous pourriez le faire, mais je me demande si vous avez vraiment besoin de créer un contrôleur local ou si vous pouvez simplement passer votre contrôleur existant au gestionnaire de connexion? Ensuite, vous pouvez passer le AbstractMessageReceiver au contrôleur et le gestionnaire de connexion n'a pas à s'inquiéter à ce sujet. – Philipp

0

Il semble que vous faites tout en un seul fil. Comme il faut du temps pour que les paquets puissent aller et venir, il est conseillé de faire un travail fastidieux dans un thread différent, et de publier le statut/résultats du thread de l'interface utilisateur. (Ou l'interface utilisateur sera gelée).

+0

En fait, j'écoute les connexions et le traitement de la requête dans un thread différent généré par CConnectionManager. – Jeeva