Partage
  • Partager sur Facebook
  • Partager sur Twitter

lister les wifis disponibles et s'y connecter

via l'api wlan en c++

    13 octobre 2017 à 21:23:57

    Pas de problème, je suis encore peu expérimenté, je ne demande qu'a apprendre et à ce qu'on me fasse des remarques, c'est comme ca que l'on apprend !

    Alors j'ai commencé à essayer d'implémenter simplement ces quatre classes mais plusieurs questions se sont posées :

    >-Wlan (peut-être en utilisant le Design Pattern "Singleton"), qui gèrerait l'utilisation du handle du Wlan, donc appel de "WlanOpenHandle" dans son constructeur et le "WlanCloseHandle" dans son destructeur (ce que ne fait jamais votre code spaghetti qui ouvre des pelletées d'handle sans jamais un fermé un seul).

    Donc il créerait les handles et ils aurait une methode getHandle (afin de respecter l'encapsulation) qui renverrait un handle ?

    le handle renvoyé pourra servir pour toutes les opérations ? (getAvilableNetworkList, getProfile, setProfile, WlanCOnnect...) ou il faudra en créer un à chaque fois.

    Concernant le Design Pattern "Singleton" que je ne connaissais pas, j'ai lu quelques articles dessus (notamment celui la : http://come-david.developpez.com/tutoriels/dps/?page=Singleton ) et je dois avouer que son utilisation et son utilité dans ce cas là m'échappent un peu...

    > http://en.cppreference.com/w/cpp/error/runtime_error

     > =>Defined in header <stdexcept>


    ah oui, suis-je bête... n'empêche que ceci :
    throw std::runtime_error(dwResult, std::generic_category());

    ne compile toujours pas :
    aucune instance du constructeur "std::runtime_error::runtime_error" ne correspond à la liste d'arguments


    pffffff...
    >Si vous avez du mal à commencer, je vous ferais l'implémentation de Wlan en mode "à l'arrache".
    je vais essayer de me débrouiller tout seul, c'est comme ca que l'on apprend mais merci quand même.

    EDIT :

    j'ai commencé l'implémentation de la classe Profils, je vous la montre avant que je fasse tout faux (j'éatais pas sur si les variables sont a utiliser en parametre ou en variables membres...)

    #pragma once
    #ifndef PROFILS
    #define PROFILS
    
    
    #include <string>
    #include <Windows.h>
    
    class Profils {
    public :
    	Profils(WLAN_AVAILABLE_NETWORK_LIST bssList, int numeroReseau, GUID GUID);
    	DWORD creerProfil(std::string password);
    	LPWSTR recupProfil();
    
    private:
    	WLAN_AVAILABLE_NETWORK_LIST bssList;
    	int numeroReseau;
    	GUID GUID;
    };
    
    #endif // !PROFILS



    -
    Edité par raphaeldesaintalbin 14 octobre 2017 à 17:54:12

    • Partager sur Facebook
    • Partager sur Twitter
    "La valeur n'attend point le nombre des années" Le Cid, Pierre Corneille, Don Rodrigue parlant au Comte
      16 octobre 2017 à 9:55:39

      J'ai une autre question plus générale : lors de l'implémentation d'une classe et que j'ai besoin d'une variable qui vient de l’extérieur, quand la passer en argument de la fonction membre ou bien en faire un attribut que l'on initialise via le constructeur ?

      par exemple, vaut mieux ca :

      #pragma once
      #ifndef PROFILS
      #define PROFILS
      
      
      #include <string>
      #include <Windows.h>
      
      class Profils {
      public :
      	Profils(WLAN_AVAILABLE_NETWORK_LIST bssList, int numeroReseau, GUID GUID);
      	DWORD creerProfil(std::string password);
      	LPWSTR recupProfil();
      
      private:
      	WLAN_AVAILABLE_NETWORK_LIST bssList;
      	int numeroReseau;
      	GUID GUID;
      };
      
      #endif // !PROFILS

      ou ca :

      #pragma once
      #ifndef PROFILS
      #define PROFILS
      
      
      #include <string>
      #include <Windows.h>
      
      class Profils {
      public :
      	DWORD creerProfil(std::string password, WLAN_AVAILABLE_NETWORK_LIST bssList, int numeroReseau, GUID GUID);
      	LPWSTR recupProfil(WLAN_AVAILABLE_NETWORK_LIST bssList, int numeroReseau, GUID GUID);
      };
      
      #endif // !PROFILS



      -
      Edité par raphaeldesaintalbin 16 octobre 2017 à 10:04:57

      • Partager sur Facebook
      • Partager sur Twitter
      "La valeur n'attend point le nombre des années" Le Cid, Pierre Corneille, Don Rodrigue parlant au Comte
        16 octobre 2017 à 18:40:02

        Ok, vos remarques montrent que vous n'êtes pas encore très à l'aise dans la POO.

        Si l'un des objectifs est de progresser dans ce domaine, c'est bien.

        Mais si c'est pour avoir rapidement un truc qui marchouille, ce n'est pas forcement le plus rapide.

        Donc, si vous ne voulez pas "progresser" en POO, signalez le pour éviter de suivre une démarche qui ne sera efficace qu'à plus long terme.

        C'est bien d'appliquer la POO dans un cas concret, mais on risque de tomber sur des trucs complexes, sans progressivité, qu'un cas d'exemple d'un cours sur le POO permet car étudié pour.

        >Donc il créerait les handles

        Une propriété cardinale d'une classe est de ne d’occuper que d'une chose, mais le faire bien.

        Donc, la classe Wlan ne devrait s'occuper que du Wlan, donc un seul handle par instance.

        > et ils aurait une methode getHandle (afin de respecter l'encapsulation) qui renverrait un handle ?

        Une autre propriété cardinale d'une classe est l'encapsulation, donc un accesseur, c'est très moyen. Il serait plus "safe" que seul le code de la class Wlan sache utiliser le "Handle". A la rigueur, pour des classes très couplées à la classe Wlan (inutilisable sans la classe Wlan), on pourrait en faire une classe "amie" de Wlan.

        Mais commencez déjà par implémenter le cycle de vie du Wlan, qui ouvre l'handle dans son constructeur et le ferme dans son destructeur.

        Puis, vous implémentez une méthode, dans la classe Wlan, qui renvoie une liste des "Interface" en utilisant la fonction "WlanEnumInterfaces", mais sous la forme d'une liste d'instance d'objet de type "Interface".

        Pour que la classe "Interface" puisse faire son action de donner la liste des "Network" disponibles, elle devrait utiliser la fonction "WlanGetAvailableNetworkList" qui nécessite l'handle du Wlan. Mais plutôt que d'utiliser une éventuelle méthode public "getHandle" de Wlan, qui permettrait à n'importe quel code de foutre le bordel sur l'handle, il serait plus "safe" de faire de la classe "Interface" une classe "amie" de la classe Wlan, via l'utilisation de friend ( http://en.cppreference.com/w/cpp/language/friend ). C'est faire confiance au développeur de la classe "Interface" pour ne pas faire de conneries.

        >le handle renvoyé pourra servir pour toutes les opérations ?

        Oui, mais en faisant en sorte que mal l'utiliser soit très compliqué.

        >getAvilableNetworkList

        Oui, mais uniquement dans la classe amie "Interface"

        >getProfile

        Idem, uniquement dans la classe amie "Interface"

        >setProfile

        Idem, uniquement dans la classe amie "Interface"

        >WlanCOnnect

        C'est une action qui, si je me trompe pas, doit être au niveau du "Network". Il faudrait dont que la classe "Network" conserve une référence vers son "Interface" hôte et qu'elle lui demande de faire la connexion. Il ne faudrait pas fournir le handle à la méthode de "Interface", mais c'est l'objet "Interface" qui se chargera de retrouver l'handle grâce à son amitié avec Wlan.

        Si vous ne voulez pas que d'autres code puisse appeler la méthode de "Interface" pour faire la connexion, vous pouvez en faire une méthode privée et rendre la classe "Network" amie de la classe "Interface".

        >ou il faudra en créer un à chaque fois.

        Non. Wlan le garde ouvert, comme dans un coffre-fort, et son cycle de vie rend cela "safe".

        >et je dois avouer que son utilisation et son utilité dans ce cas là m'échappent un peu...

        Le lien n'est pas forcement évidant. C'est une habitude pour moi de faire les architectures en couche indépendantes.

        Ici, le Singleton pour la classe Wlan, c'est dans la perceptive de faire de la couche réseau, une couche indépendante et facilement interchangeable avec une autre implémentation.

        Mais on n'est pas obligé, et on peut le faire après, si la conception de la classe Wlan est "soignée".

        >ne compile toujours pas :

        Message d'erreur complet, SVP.

        Mais bon, la doc indique que j'ai écris de conneries, que j'ai chopé sur le net. Il faut l'adapter mais c'est pas super complexe.

        Le principal, c'est de faire des exceptions et pas des codes retours à la C.

        >je vais essayer de me débrouiller tout seul, c'est comme ca que l'on apprend mais merci quand même.

        Vous devriez commencer par la classe Wlan, ça serrait plus simple.

        >j'ai commencé l'implémentation de la classe Profils,

        Attention, vous utilisez à la fois "#pragma once" et les "header guard traditionnel", ça fait plus d'emmerde pour aucun gain.

        Soyez plus "spécifique" dans vos "#include", <windows.h> dans un cpp, c'est un peu beaucoup.

        Utilisez les header spécifique pour marquer les dépendances de votre code.

        Ici, vous utilisez les structures de l'interface C dans votre API.

        Il faut essayer de faire en sorte qu'elles n’apparaissent pas dans l'API das classes, pour qu'elles soient le plus C++ possible, sans archaïsme C,et circonscrire l'utilisation du C à quelques méthodes qui ne font rien en paraitre (usage d'exception et pas de code retour, de classe C++ et pas de structure C en paramètre, principalement).

        Vous devriez commencez par Wlan, ainsi, vous disposeriez de plus de classe C++ lors de l'implémentation de la classe "Profile".

        Une méthode "creerProfile", ça sent pas bon. Les seules méthodes qui doivent créer un objet (si l'on ne met pas en place un Design Pattern de création, Singleton, Builder, etc...) sont les constructeurs. C'est le seul moyen d'être sûr qu'une fois créé, l'objet est complètement opérationnel.

        J'ai l'impression qu'un profile est lié a une interface réseau ou à un réseau lui-même, je pense donc que seule la classe qui doit être à même de créer un profile doit être la classe liée ("Interface" ou Network, via un constructeur "private" et donc rendre la classe lié "amie" de la classe Profile).

        Mais je ne suis pas sûr que l'existence de la classe "Profile" soit nécessaire, si elle n'est utilisée quand n'interne de la classe liée.

        La méthode "recupProfil", j'ai du mal à voir pourquoi vous en aurez besoin.

        Avant de concevoir comment implémenter une classe, commencez par concevoir un code client qui utilise une ou plusieurs de ces classes et qui doit en savoir le moins possible sur l'implémentation de ces classes.

        Du genre :

        void faireCoucouAuReseauWifi()
        {
           //Wlan wlan = Wlan.getInstance(); //utilisation d'un Singleton.
           Wlan wlan{}; //utilisation d'un constructeur sans paramètre donc RAII=> fermeture automatique
        
           auto interfaces = wlan.getInterfaces();
        
           if(interfaces.size()>0)
           {
              auto networks = interfaces[0].getNetworks();
        
              if(networks.size()>0)
              {
                 networks[0].connect(WlanNotification); // en utilisant un profile par défaut, par exemple, et notifiant la méthode WlanNotification pour les différentes notification.
                 do
                 {
        ...
                 }while(...);
              }
           }
        }


        EDIT:

        > que j'ai besoin d'une variable qui vient de l’extérieur, quand la passer en argument de la fonction membre ou bien en faire un attribut

        Il ne faut pas donner d'information sur l'implémentation de la classe. Donc, ne pas demander de paramètres pour une méthode public qui est lié a comment est implémenté la classe.

        Donc, commencez par concevoir l'API d'une classe avant de chercher à savoir comment l'implémenter.

        cf. mon exemple de code client => implémenter ce  selon quelque chose de logique pour une personne ne connaissant rien sur les coulisses de la classe.

        -
        Edité par bacelar 16 octobre 2017 à 18:44:00

        • Partager sur Facebook
        • Partager sur Twitter
        Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
          18 octobre 2017 à 21:51:52

          "Ok, vos remarques montrent que vous n'êtes pas encore très à l'aise dans la POO.

          Si l'un des objectifs est de progresser dans ce domaine, c'est bien.

          Mais si c'est pour avoir rapidement un truc qui marchouille, ce n'est pas forcement le plus rapide.

          Donc, si vous ne voulez pas "progresser" en POO, signalez le pour éviter de suivre une démarche qui ne sera efficace qu'à plus long terme.

          C'est bien d'appliquer la POO dans un cas concret, mais on risque de tomber sur des trucs complexes, sans progressivité, qu'un cas d'exemple d'un cours sur le POO permet car étudié pour."

          Effectivement, la POO est un sujet que je ne maitrise pas très bien, mais bien sur que je veux progresser !

          Vous parlez d'un cours de POO, vous avez une référence en tête ?

          ">Donc il créerait les handles

          Une propriété cardinale d'une classe est de ne d’occuper que d'une chose, mais le faire bien.

          Donc, la classe Wlan ne devrait s'occuper que du Wlan, donc un seul handle par instance.

          > et ils aurait une methode getHandle (afin de respecter l'encapsulation) qui renverrait un handle ?

          Une autre propriété cardinale d'une classe est l'encapsulation, donc un accesseur, c'est très moyen. Il serait plus "safe" que seul le code de la class Wlan sache utiliser le "Handle". A la rigueur, pour des classes très couplées à la classe Wlan (inutilisable sans la classe Wlan), on pourrait en faire une classe "amie" de Wlan.

          Mais commencez déjà par implémenter le cycle de vie du Wlan, qui ouvre l'handle dans son constructeur et le ferme dans son destructeur."

          Au pire, je créé un handle directement dans le constructeur de chaque classe, c'est 5 lignes...

          "Vous devriez commencez par Wlan, ainsi, vous disposeriez de plus de classe C++ lors de l'implémentation de la classe "Profile"."

          Oui mais elle serait inutilisable puisque plein de ses arguments viendront de la classe Network.

          "Une méthode "creerProfile", ça sent pas bon. Les seules méthodes qui doivent créer un objet (si l'on ne met pas en place un Design Pattern de création, Singleton, Builder, etc...) sont les constructeurs. C'est le seul moyen d'être sûr qu'une fois créé, l'objet est complètement opérationnel.

          J'ai l'impression qu'un profile est lié a une interface réseau ou à un réseau lui-même, je pense donc que seule la classe qui doit être à même de créer un profile doit être la classe liée ("Interface" ou Network, via un constructeur "private" et donc rendre la classe lié "amie" de la classe Profile).

          Mais je ne suis pas sûr que l'existence de la classe "Profile" soit nécessaire, si elle n'est utilisée quand n'interne de la classe liée.

          La méthode "recupProfil", j'ai du mal à voir pourquoi vous en aurez besoin."

          C'est vrai, le code la méthode creerProfil devrait être compris dans le constructeur mais il ne doit s’exécuter si il n'y a pas déjà de profil, mais c'est la que la classe Network va nous aider car il y a une variable qui dit si il existe un profil pour le réseau spécifié... c'est "propre" de mettre une condition dans une classe ?

          "Avant de concevoir comment implémenter une classe, commencez par concevoir un code client qui utilise une ou plusieurs de ces classes et qui doit en savoir le moins possible sur l'implémentation de ces classes."

          alors la, j'ai pas bien saisi... le code d'en dessous non plus d'ailleurs...

          "> que j'ai besoin d'une variable qui vient de l’extérieur, quand la passer en argument de la fonction membre ou bien en faire un attribut

          Il ne faut pas donner d'information sur l'implémentation de la classe. Donc, ne pas demander de paramètres pour une méthode public qui est lié a comment est implémenté la classe."

          Mais je fais comment alors ? Je déclare les classes amies ?

          "Donc, commencez par concevoir l'API d'une classe avant de chercher à savoir comment l'implémenter.

          cf. mon exemple de code client => implémenter ce  selon quelque chose de logique pour une personne ne connaissant rien sur les coulisses de la classe."

          Ok, donc j'avais pas vraiment conscience de créer une API...

          Donc il faut que globalement, toutes les variables se transmettent d'une classe à l'autre sans jamais passer devant l'utilisateur, tout doit lui être caché... C'est donc le principe d'amitié que je dois encore utiliser. Je me renseigne plus dessus car je n'ai pas l'habitude de l'utiliser...

          • Partager sur Facebook
          • Partager sur Twitter
          "La valeur n'attend point le nombre des années" Le Cid, Pierre Corneille, Don Rodrigue parlant au Comte
            19 octobre 2017 à 10:53:49

            >Vous parlez d'un cours de POO, vous avez une référence en tête ?

            Non, désolé, c'est un bon nouveau sujet pour le forum. ;)

            >Au pire, je créé un handle directement dans le constructeur de chaque classe, c'est 5 lignes...

            Pourquoi au pire ? C'est pas ce qu'il y a de plus simple ???

            >Oui mais elle serait inutilisable puisque plein de ses arguments viendront de la classe Network.

            Et ? Si vous avez besoin de "plein" d'argument de Network, pourquoi ne pas passer juste un objet de type Network ?

            Et si un profile est lié à un network, vous passez la référence du Network comme argument du constructeur du profile et vous le stockez dans un champ de la classe. Ainsi, vous n'avez plus à le transmettre en argument des méthodes.

            Commencez par concevoir les classes que le code "client" utilisera en premier, comme Wlan. Puis concevez les autres en fonction des premières et pour simplifier leur usage dans la code "client".

            >car il y a une variable qui dit si il existe un profil

            "Variable", ça veut pas dire grand chose. Vous pensez à un champ, non ?

            >c'est "propre" de mettre une condition dans une classe ?

            Idem pour condition, c'est pas clair.

            Ce qu'il faut, c'est que les classes soient simples d'utilisation et qu'elles ne nous obligent pas à savoir comment elles travaillent en interne.

            Donc, si profile n'est utile que dans le Network, il ne devrait pas montrer ce champ et le gérer en interne.

            >alors la, j'ai pas bien saisi... le code d'en dessous non plus d'ailleurs...

            C'est juste un exemple de code "client" possible.

            Ne vous concentrez pas sur comment vous allez faire les choses, mais comment vous allez offrir des services intéressants pour le code "client".

            Ici, je me suis dit, en me mettant dans la peau d'un utilisateur des classes, comment je voudrais qu'on me présente la fonctionnalité qui m’intéresse "être notifié de l'activité sur le premier réseau Wifi, sur la première interface réseau wifi".

            Si vous avez plus simple tout en restant "générique", pas de problème, montrez-nous comment vous pensez que l'utilisateur devrait utiliser les services de vos classes. (ne pensez pas à l'implémentation)

            >Mais je fais comment alors ? Je déclare les classes amies ?

            Ne cherchez pas à voir comment faire les choses, commencez par concevoir ce que chaque classe doit rendre comme service.

            Après, on aura toujours des moyens pour faire le bidule et le code qui les utiliseront ne changera pas, même si on change complètement comment c'est fait en interne.

            Pour les classes amies : http://en.cppreference.com/w/cpp/language/friend

            >Ok, donc j'avais pas vraiment conscience de créer une API...

            Oui, et c'est très important.

            > toutes les variables se transmettent d'une classe à l'autre sans jamais passer devant l'utilisateur

            Oui, et si possible, le moins de "variables" entre les classes pour qu'elles soient les plus indépendantes les unes des autres.

            >tout doit lui être caché...

            Moins le code client en sait sur comment sont fait les choses plus il est simple de changer la manière de faire en interne.

            >C'est donc le principe d'amitié que je dois encore utiliser.

            Si nécessaire, mais commencer par le quoi (l'API) plutôt que par le comment. L'amitié ne sert qu'au comment et donc inutile de s'en préoccupé maintenant.

            Concevez l'API, puis on verra comment l'implémenter.

            • Partager sur Facebook
            • Partager sur Twitter
            Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
              24 octobre 2017 à 19:31:14

              Rebonjour et désolé pour le retard, j'ai du faire face à deux petits contretemps (travail et la box qui a lâché, on a du la changer)

              ">c'est "propre" de mettre une condition dans une classe ?

              Idem pour condition, c'est pas clair."

              En gros, selon si l'ordinateur a déjà un profil de connexion, le constructeur utilise seulement WlanGetProfile ou WlanSetProfile puis WlanGetProfile. le WlanGetProfile étant de toute façon appelé, ca ferait en gros :

              si il y n'y a pas de profil
              
              {
              
                    WlanSetProfile
              
              } WlanGetProfile

              Sinon, en ce qui concerne la conception de l'API :

              - une classe Wlan qui gérerait la connexion et qui récupérerait les informations nécessaires.

              - une classe Profile qui s'occuperait d’éventuellement créer un profil si nécessaire puis en tout les cas le récupère.

              - une classe Interfaces qui afficherait les interfaces wifi disponibles et obtiendrait des infos telles que : le GUID, le nom de l'interface auquel on doit se connecter etc...

              il faudra voir en ce qui concerne comment effectuer le partage des données entre les classes, mais ca c'est de implémentation, on s'en occupe pas encore, c'est bien ca ?

              Pour ce qui concerne le topic pour les cours de conception je crois que le club de lecture est sur un livre qui traite justement d'un livre sur le sujet, j'attends de voir ce que ca va donner.

              Concernant la conception, j'ai du mal à définir la limite entre conception et implémentation, car dire quelle classe à besoin de quoi c'est de la conception ? dire qui accédé a quoi et comment c'est de l’implémentation ?

              Merci de m'aider autant,

              Raphael

              -
              Edité par raphaeldesaintalbin 24 octobre 2017 à 19:33:28

              • Partager sur Facebook
              • Partager sur Twitter
              "La valeur n'attend point le nombre des années" Le Cid, Pierre Corneille, Don Rodrigue parlant au Comte
                25 octobre 2017 à 17:00:51

                L'objectif d'une classe c'est de rendre des services et que l'utilisation de ces services soit plus simple que de faire "tout soi-même".

                C'est une stratégie proche de "séparer pour mieux régner".

                Si vous planquez toute la gestion des profiles dans une classe.

                Si le code client de la classe se fout de la "gestion" des profiles, l'utilisation de la classe simplifiera le code client, donc oui, c'est très bien de planquer la "gestion" des profiles à l'utilisateur de la classe.

                >- une classe Wlan qui gérerait la connexion

                "gerer", c'est beaucoup trop vague, et si c'est pour des "connexion" autant avoir une classe "connexion" qui représente une connexion et rien d'autre.

                La classe "Wlan" devrait être un point d'entrée des fonctionnalité Wlan que vous voulez donner au code client.

                Comme "créer une connexion" avec une méthode "CreateConnection" qui renverrait un objet/instance de la classe "Connection".

                etc...

                >et qui récupérerait les informations nécessaires.

                Les informations pour créer une connexion, dans la classe en charge de la créer.

                Les informations nécessaires à son utilisation dans la classe Connection.

                >- une classe Profile qui s'occuperait d’éventuellement créer un profil si nécessaire

                Ça, c'est dans l'instance de la classe qui crée un objet "Profile", pas dans la classe "Profile" elle-même ni dans une des ces instances.

                >- une classe Interfaces qui afficherait les interfaces wifi disponibles

                Je vous conseille de séparer l'affichage du reste du code.

                Et de nouveau, c'est la classe qui "gère" les Interfaces qui doit avoir les mécanismes de recensement/accès, pas la classe Interface elle-même.

                Si par "Interfaces", vous entendez un ensemble d'interfaces, j'ai du mal à voir ça valeur ajouter par rapport à une std::list<Interface> ou std::map<std::string, Interface> comme champ membre de la classe Wlan, par exemple.

                >et obtiendrait des infos telles que : le GUID, le nom de l'interface auquel on doit se connecter etc...

                Oui, dans une classe "Interface", pas "Interfaces"

                >il faudra voir en ce qui concerne comment effectuer le partage des données entre les classes,

                Éviter de voir les classes comme des conteneurs de données, mais comme des fournisseurs de services.

                Il faut qu'il y ait le moins de dépendances entre les classes pour pouvoir changer une classe sans avoir à changer les autres.

                Si elles se partagent/transmettent des données, il y a des chances que les modifications d'implémentation se propagent de proche en proche (modification "shot-gun", qui demande à modifier plein de code, c'est pas bon).

                Il y a toujours moyen pour que les informations nécessaires à l'usage d'une méthode d'un objet soient fournies (paramètre de la méthode, paramètre du constructeur de l'objet + champs associés, etc...)

                >mais ca c'est de implémentation, on s'en occupe pas encore, c'est bien ca ?

                OUI !!! ;)

                >Concernant la conception, j'ai du mal à définir la limite entre conception et implémentation

                On conception, 0 ligne de code, juste des diagrammes de classes, des diagrammes d'objet, des cas d'usages, => Outils à la UML.

                Je ne suis pas un adepte du modèle de conception cycle en V (ou cascade) qui demande à tout concevoir avant de commencer l'implémentation, mais il faut déjà au minimum avoir conçu un cas d'usage important avant de l'implémenter (cycle prototyping, SCRUM, méthodes agiles)

                >, car dire quelle classe à besoin de quoi c'est de la conception ?

                C'est ta solution que tu conçois, les classes ne sont que l'émanation de cette conception.

                Les classes à concevoir sont celles nécessaire pour les cas d'usage à implémenter.

                >dire qui accédé a quoi et comment c'est de l’implémentation ?

                Non, c'est de la conception.

                • Partager sur Facebook
                • Partager sur Twitter
                Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                  31 octobre 2017 à 16:31:49

                  Bonjour !

                  J'ecris cette réponse depuis mon téléphone car c'est les vacances scolaires et je n'ai donc pas mon ordinateur !

                  Je continue a suivre le sujet mais je ne pourrais pas vous répondre d'ici la fin des vacances !

                  merci de votre compréhension,

                  Raphael

                  • Partager sur Facebook
                  • Partager sur Twitter
                  "La valeur n'attend point le nombre des années" Le Cid, Pierre Corneille, Don Rodrigue parlant au Comte
                    6 novembre 2017 à 22:14:45

                    Re !

                    je suis en train de faire un petit schéma que je vous partagerais demain concernant la conception de l'API ! (j'aime bien les schémas....)

                    à demain !

                    • Partager sur Facebook
                    • Partager sur Twitter
                    "La valeur n'attend point le nombre des années" Le Cid, Pierre Corneille, Don Rodrigue parlant au Comte
                      10 novembre 2017 à 15:27:42

                      bon, j'ai fais un schéma très rapidement mais il est mal fait et très peu représentatif, c'est juste en attendant que je maitrise mieux l'UML et que je fasse un truc mieux :

                      -
                      Edité par raphaeldesaintalbin 10 novembre 2017 à 15:28:23

                      • Partager sur Facebook
                      • Partager sur Twitter
                      "La valeur n'attend point le nombre des années" Le Cid, Pierre Corneille, Don Rodrigue parlant au Comte
                        10 novembre 2017 à 19:23:38

                        Je ne suis pas très friand des schémas simplifiés UML.

                        Je trouve ça pratique pour la présentation de Design Pattern car c'est générique, mais quand on doit pondre du code, c'est plein d'ambiguïtés.

                        Ce que je comprends de ce diagramme :

                        Il y a une classe "wlan" qui contient un champ de nom "profile" de type? "Profile" ??

                        (le laïus sur la manière d'initialiser ce champ, c'est pas important, des Design Pattern de Création, c'est pas ça qui manque)

                        La classe "wlan" a une méthode "connexion"

                        Après, le reste, c'est beaucoup moins claire (construction Vs affichage, etc...).

                        Le caractère multiple (plusieurs interfaces) de "Interface" n'est pas clair et les mécanismes d'initialisation, c'est comme pour profile, c'est un simple détaille d'implémentation.

                        En gros, si je résume :

                        class Profile
                        {
                            Profile(???){...};
                        public :
                            static std::unique_ptr<Profile> createProfile(???){...};
                        }
                        
                        class Interface
                        {
                            Interface(???){...};
                        public :
                            static std::unique_ptr<Interface> createInterface(???){...};
                        }
                        
                        classe wlan
                        {
                            std::unique_ptr<Profile> profile;
                            std::vector<std::unique_ptr<Interface>> interfaces;
                        
                            wlan()
                            {
                        ...
                                profile = Profile::createProfile();
                        ...
                                for(......)
                                {
                                    interfaces.add(Interface::createInterface(???));
                                }
                        ...
                            };
                        
                        public :
                            connection(){...};
                        
                            static getInstance(){...};
                        }
                        

                        (code à ventiler entre .h et .cpp)
                        Je trouve le code plus clair, plus concis et moins ambiguë.

                        -
                        Edité par bacelar 10 novembre 2017 à 19:24:18

                        • Partager sur Facebook
                        • Partager sur Twitter
                        Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                          13 novembre 2017 à 20:03:08

                          Excusez moi, je viens de voir en regardant le forum que ma réponse n'était pas partie !

                          je disais donc que il y avait certaines choses inconnues pour moi dans ce code.

                          Tout d'abord le std::unique_ptr. j'ai cru comprendre que c'était un pointeur "intelligent" qui détruit l'objet pointé à sa destruction.

                          ensuite le getInstance(), je sais que c'est pour le design pattern singleton et j'ai lu des cours la dessus mais je vais continuer à me renseigner car j'ai un peu de mal avec son implémentation.

                          sinon, pourriez vous me renseigner sur ce morceau du code :

                                  for(......)
                                  {
                                      interfaces.add(Interface::createInterface(???));
                                  }

                          ?

                          merci d'avance,

                          Raphael

                          -
                          Edité par raphaeldesaintalbin 13 novembre 2017 à 20:09:29

                          • Partager sur Facebook
                          • Partager sur Twitter
                          "La valeur n'attend point le nombre des années" Le Cid, Pierre Corneille, Don Rodrigue parlant au Comte
                            14 novembre 2017 à 15:04:15

                            Votre cas d'utilisation de la POO, c'est pas un cas "basique", il y a une grosse marche conceptuelle.

                            >Tout d'abord le std::unique_ptr. j'ai cru comprendre que c'était un pointeur "intelligent"

                            Tout à fait.

                            > qui détruit l'objet pointé à sa destruction.

                            Oui, mais pas que.

                            Ici, c'est surtout pour indiquer et gérer le fait que seul un objet est "propriétaire" de l'objet pointé.

                            Par propriétaire, c'est la gestion de la durée de vie de l'objet.

                            Ici, c'est l'objet  de classe "wlan" qui est le propriétaire des instances de "Interface". Personne d'autre ne créera d'Interface et c'est "wlan" qui détruira ces objet "Interface" qui il le jugera opportun.

                            Idem pour "Profile".

                            >ensuite le getInstance(), je sais que c'est pour le design pattern singleton

                            Oui.

                            Ici "wlan" est un singleton parce que je pense qu'avoir plusieurs objets de ce type en même temps peut peut-être foutre la grouille. Mais peut-être que cela est inutile, à voir. Mais j'ai l'impression aussi qu'un Singleton simplifierait l"usage de la classe dans le code métier, mais à voir aussi.

                            Comme on ne veut pas que les objets de type "Interface" ou "Profile" se fassent cloner par un constructeur de copie lors d'un passage par valeur à une fonction, je crée, pour chacun de ces classes, un constructeur privé et une méthode statique dédiés à leur création "createXXX". On pourrait raffiner le Design Pattern de création pour ces classes, mais c'est l'idée de ne pas laisser faire des trucs qui peuvent mettre la grouille comme le clonage.

                            L'objectif du constructeur de "wlan", c'est d'avoir un objet complètement opérationnel en sortie du constructeur.

                            "wlan" doit pouvoir donner la liste des interfaces.

                            Donc, dans le constructeur, on fait une boucle qui va créer toutes les interfaces qui sont liée à "wlan".

                            Le "for(.....)" correspondrait à l'usage de la valeur retournée par l'appel de "WlanEnumInterfaces".

                            "createInterface(???)" est le code qui sera en charge de créer on objet "Interface" à partir des informations retournées par "WlanEnumInterfaces". "????" c'est à vous de remplir avec les paramètres pertinents à la création d'un objet "Interface".

                            • Partager sur Facebook
                            • Partager sur Twitter
                            Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                              19 novembre 2017 à 14:25:07

                              Très bien !

                              J'ai pris le temps de lire un peu plus de choses sur le design pattern singleton et je pense qu'il est plutôt adapté.

                              Même si il n'est pas obligatoire, je pense que ce serait toujours intéressante et enrichissant d'essayer de l’implémenter...

                              Comme nous avons fini la conception de l'API (du moins je pense), on passe à l'implémentation maintenant ?

                              • Partager sur Facebook
                              • Partager sur Twitter
                              "La valeur n'attend point le nombre des années" Le Cid, Pierre Corneille, Don Rodrigue parlant au Comte
                                20 novembre 2017 à 9:39:11

                                As-tu déjà essayé "d'utiliser" l'API que tu as conçu ?

                                Par cela, je veux dire, faire un code client de tes classes qui veut faire des trucs.

                                Si le code client te parait simple pour une personne qui n'a pas écrit le code d'implémentation des classes, c'est que l'API est bonne.

                                Si vous faites cela après avoir implémenter les classes, vous avez de plus forte chance d'utiliser vos connaissances de la manière dont vous avez implémenté les classes dans le code client.

                                Cela biaiserait donc votre évaluation de la qualité de l'API.

                                Le code client compilera grâce aux .h, c'est juste l'édition qui bloquera. Ce qui n'est pas important pour évaluer la "praticité" de l'API.

                                • Partager sur Facebook
                                • Partager sur Twitter
                                Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                                  20 novembre 2017 à 14:51:51

                                  Donc je dois écrire les prototypes des classes dans le(s) header(s) ?

                                  Je pense que c'est mieux de créer un header et un fichier source par classe mais est-ce la meilleure solution ?

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                  "La valeur n'attend point le nombre des années" Le Cid, Pierre Corneille, Don Rodrigue parlant au Comte
                                    20 novembre 2017 à 15:30:57

                                    >Donc je dois écrire les prototypes des classes dans le(s) header(s) ?

                                    Oui, juste les méthodes publiques suffiront à faire une compilation du code client.

                                    Par prototypes, c'est les déclarations, pas les définitions.

                                    >Je pense que c'est mieux de créer un header et un fichier source par classe mais est-ce la meilleure solution ?

                                    Oui, mais aussi des fichiers d'en-tête ne correspondant à aucune classe mais à un module/composant, comme le module "network" ou le module "wifi".

                                    Ces fichiers d'en-tête contiendront les #include aux fichiers d'en-tête des classes "publiques" du module : les classes faisant partie de/constituant l'API du module, en quelque-sorte.

                                    Pour faire le code client, vous ne faites que l'include de "monComposant.h" dans le cpp du code client.

                                    Vous n'avez pas besoins des .cpp pour compiler le code client.

                                    En faisant ainsi, vous concevez l'API selon l'utilisabilité par le code client et pas comme une redite de l'implémentation des composants.

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                    Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                                      22 novembre 2017 à 23:20:07

                                      En essayant de faire les déclarations, je me suis rendu compte que je ne comprenais pas bien cette ligne :

                                       static std::unique_ptr<Profile> createProfile(???){...};


                                      pourriez vous m'éclairer ?

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                      "La valeur n'attend point le nombre des années" Le Cid, Pierre Corneille, Don Rodrigue parlant au Comte
                                        23 novembre 2017 à 11:28:46

                                        Une méthode static qui crée un objet "Profile", le Design Patern Factory.

                                        Ici les "(???)", c'est l'ensemble des paramètres dont a besoin la factory pour construire un profile.

                                        Il faut remplacer ça par les arguments nécessaires.

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                        Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                                          27 novembre 2017 à 19:08:08

                                          J'ai lu un peu sur ce design pattern et je n'ai pas bien compris son utilité et son implémentation ici, la fonction statique créé un objet de lui issu de la classe ou la fonction est elle même rangée et on récupère un pointeur sur l'objet que l'on vient de créer ?
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                          "La valeur n'attend point le nombre des années" Le Cid, Pierre Corneille, Don Rodrigue parlant au Comte
                                            27 novembre 2017 à 19:43:46


                                            >je n'ai pas bien compris son utilité

                                            bacelar a écrit:

                                            Comme on ne veut pas que les objets de type "Interface" ou "Profile" se fassent cloner par un constructeur de copie lors d'un passage par valeur à une fonction, je crée, pour chacun de ces classes, un constructeur privé et une méthode statique dédiés à leur création "createXXX". On pourrait raffiner le Design Pattern de création pour ces classes, mais c'est l'idée de ne pas laisser faire des trucs qui peuvent mettre la grouille comme le clonage.

                                            La création/et Destruction des objets de type "Profile" doivent être étroitement surveillées pour éviter d'avoir des profile en double ou périmés/libérés etc... . L'utilisation d'un Design Pattern de création permet de faciliter cette surveillance.

                                            Si j'ai bien compris, la gestion des profiles doit être interne à la classe Wlan (contrairement aux Interfaces). Le code client ne devrait pas voir de "Profile" apparaître dans son code, donc, la classe "Profile" ne devrait pas être une classe public de votre module de gestion du Wlan. Donc, vous n'êtes pas obligé de mettre en place tout de suite ce Design Pattern.

                                            Tant que la classe "Profile" n'est pas utilisable depuis l'extérieur de Wlan, vous pouvez changer complètement la manière dont vous gérer les "Profile" sans que cela ne change le code client de Wlan.

                                            > et son implémentation ici

                                            Son implémentation est très simple, vu que l'API sous-jacente est une API C. Vous faite juste une petite transformation des paramètre pour qu'ils collent à ceux de l'API C.

                                            >la fonction statique créé un objet de lui issu de la classe

                                            ???

                                            Vu de l’extérieur, cette méthode statique me renvoie un pointeur sur un Profile et celui qui le récupère (le code appelant de la méthode) est responsable/propriétaire, c'est donc au code appelant de gérer la destruction de cet objet dont un pointeur sur lui a été retourné.

                                            Mon raisonnement, j'ai un objet que je ne veut pas qu'il soit facilement clonable et doit une représentation (un handle ici) est managé par une API C, j'utilise instinctivement une Factory pour avoir directement les propriétés que je veut sur l'objet créé ainsi qu'une implémentation évidente, car une méthode statique/fonction libre C++ est très proche d'une fonction C.

                                            Mais si cela devient trop abstrait, faites un premier jet et on verra comment fignoler le bidule.

                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                            Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                                              13 décembre 2017 à 23:31:21

                                              Bonjour !

                                              Excusez moi d'avoir pris tant de temps à vous répondre, mais j'ai eu quelques soucis de santé et puis le brevet blanc m'a prit du temps...

                                              Revenons à nos moutons : j'ai commencé à écrire les headers et je vous envoie donc ce que j'ai fait pour l'instant.

                                              >Mais si cela devient trop abstrait, faites un premier jet et on verra comment fignoler le bidule.

                                              exactement ca.

                                              Voici ce que j'ai obtenu :

                                              profil.h

                                              #pragma once
                                              #include <memory> class Profile { Profile(); public: static std::unique_ptr<Profile> createProfile(); };

                                              interfaces.h

                                              #pragma once
                                              class interfaces { interfaces(); };

                                              network.h

                                              #pragma once
                                              #include <memory> #include <vector> #include <Windows.h> class wlan { friend class profil; std::unique_ptr<Profile> profile; std::vector<std::unique_ptr<Interface>> interfaces; public: wlan(); };

                                              Wifi.cpp

                                              // WifiPropre.cpp : définit le point d'entrée pour l'application console.
                                              //
                                              #include "profil.h"
                                              #include "interface.h"
                                              #include "interfaces.h"
                                              #include "network.h"
                                              
                                              
                                              int main()
                                              {
                                                  return 0;
                                              }


                                              Je suppose que il y aura plein de choses à modifier, mais je dois avouer que il y a beaucoup de nouveaux concepts, et je n'étais pas habitué à la POO ni aux différents design patterns, mais je suis extrêmement désireux d'apprendre !

                                              Merci d'avance

                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                              "La valeur n'attend point le nombre des années" Le Cid, Pierre Corneille, Don Rodrigue parlant au Comte
                                                14 décembre 2017 à 10:39:27

                                                Ok, c'est un bon début.

                                                Mais j'aurais mis le "friend" entre wlan et Profile dans l'autre sens.

                                                Essayes de respecter des conventions de codage comme tous les noms de classe en CamelCase ou en pascalCase, mais pas les 2.

                                                Le snake_case de la STL est un autre choix.

                                                Peu importe ton choix, mais essayes de t'y tenir.

                                                Ne pas utiliser le snake_case permet de facilement distinguer ton code/tes classes de ceux de la STL.

                                                L'include de "windows.h" dans "network.h", c'est pas une bonne idée, il faut le minimum d'include dans le .h. Transfert cet include dans "network.cpp".

                                                Essayes de faire en sorte que le nom du fichier corresponde au nom de la classe, ou de la classe principale, qui est dans le fichier (network.h ?? wlan).

                                                Je ne vois pas le contenu de "Wifi.cpp".

                                                N'inclus que le strict minimum dans "WifiPropre.cpp".

                                                Généralement, le type de classe que tu crées ici n'est pas à usage unique. Elles doivent être réutilisable facilement dans plusieurs projet. C'est pour cela qu'on en ferait un projet distinct de type "librairie/bibliothèque".

                                                Le point d'entée n'existe pas dans une bibliothèque.

                                                Même si pour l'instant tu ne comptes pas en faire une bibliothèque, je pense qu'il faut en tenir compte dans ton nom de fichier contenant le point d'entrée du programme utilisant la future bibliothèque, comme "TestConcoleWifiLib.cpp".

                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                                                  19 décembre 2017 à 20:24:15

                                                  Bonjour,

                                                  Je vous répondrais ce week-end ou après Noël car je vais être indisponible cette semaine

                                                  Raphael

                                                  -
                                                  Edité par raphaeldesaintalbin 29 décembre 2017 à 17:33:07

                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                  "La valeur n'attend point le nombre des années" Le Cid, Pierre Corneille, Don Rodrigue parlant au Comte
                                                    15 janvier 2018 à 10:58:29

                                                    Bonjour et désolé de cette longue absence, me voila de nouveau disponible.

                                                    J'utilise personnellement le CamelCase pour les classes et le pascalCase pour les variables/fonctions.

                                                    J'ai commencé à rédiger le constructeur de Wlan et je vous donne donc la dernière version de mon code. Il y aura sans aucun doute des changements à faire.

                                                    Wifi.cpp

                                                    #include "profil.h"
                                                    #include "interface.h"
                                                    #include "interfaces.h"
                                                    #include "wlan.h"
                                                    
                                                    int main()
                                                    {
                                                    	return 0;
                                                    }

                                                    wlan.h

                                                    #pragma once
                                                    #include <memory>
                                                    #include <vector>
                                                    #include <iostream>
                                                    #include <Windows.h>
                                                    #include "profil.h"
                                                    #include "interface.h"
                                                    #include "interfaces.h"
                                                    
                                                    class Wlan
                                                    {
                                                    	std::unique_ptr<Profile> profile;
                                                    	std::vector<std::unique_ptr<Interface>> interfaces;
                                                    public:
                                                    	Wlan();
                                                    };

                                                    wlan.cpp

                                                    #include "wlan.h"
                                                    #pragma warning(disable : 4018)
                                                    
                                                    Wlan::Wlan()
                                                    {
                                                    	std::string SSID;
                                                    	std::cout << "Saissisez le nom du réseau auquel vous voulez vous connecter." << std::endl;
                                                    	std::string password;
                                                    	std::cout << "veuillez saisir le mot de passe." << std::endl;
                                                    	interfaces = Interfaces::creerInterfaces();
                                                    	for (int i(0); i < interfaces.size(); i++)
                                                    	{
                                                    		if (interfaces[i]->nomInterface == SSID)//si le nom du réseau saisi est trouvé dans la liste on créé un profile
                                                    		{
                                                    			profile = Profile::createProfile(SSID, password);
                                                    			break;
                                                    		}
                                                    		std::cerr << "ERREUR : le réseau spécifié est introuvable, le programme va s'arreter." << std::endl; //si on ne trouve pas le reseau dans la liste
                                                    	}
                                                    }

                                                    profil.h

                                                    #pragma once
                                                    #include <memory>
                                                    #include <string>
                                                    
                                                    class Profile
                                                    {
                                                    	friend class Wlan;
                                                    	Profile();
                                                    public:
                                                    	static std::unique_ptr<Profile> createProfile(std::string SSID, std::string password);
                                                    };

                                                    profil.cpp

                                                    #include <string>
                                                    #include <iostream>
                                                    #include "profil.h"
                                                    
                                                    
                                                    std::unique_ptr<Profile> Profile::createProfile(std::string SSID, std::string password)
                                                    {
                                                    	std::cout << SSID << " " << password << std::endl; //uniquement pour le débug
                                                    	system("pause");
                                                    	return std::unique_ptr<Profile>();
                                                    }
                                                    

                                                    interface.h

                                                    #pragma once
                                                    #include <memory>
                                                    #include <string>
                                                    class Interface { friend class Wlan; Interface(); std::string nomInterface; public: static std::unique_ptr<Interface> createInterface(); };

                                                    interface.cpp

                                                    #include "interface.h"
                                                    
                                                    Interface::Interface()
                                                    {
                                                    }
                                                    
                                                    std::unique_ptr<Interface> Interface::createInterface()
                                                    {
                                                    	return std::unique_ptr<Interface>();
                                                    }

                                                    interfaces.h

                                                    #pragma once
                                                    #include <vector>
                                                    #include <memory>
                                                    #include "interface.h"
                                                    class Interfaces
                                                    {
                                                    public:
                                                    	Interfaces();
                                                    	static std::vector<std::unique_ptr<Interface>> creerInterfaces();
                                                    };

                                                    interfaces.cpp

                                                    #include "interfaces.h"
                                                    
                                                    Interfaces::Interfaces()
                                                    {
                                                    }
                                                    
                                                    std::vector<std::unique_ptr<Interface>> Interfaces::creerInterfaces()
                                                    {
                                                    	return std::vector<std::unique_ptr<Interface>>();
                                                    }
                                                    

                                                    J'attends de voir ce qu'il faut changer avant de commencer à écrire les autres constructeurs et de commencer l'implémentation.

                                                    Bien à vous,

                                                    Raphaël

                                                    PS : après cette longue absence je vais être beaucoup plus disponible.

                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                    "La valeur n'attend point le nombre des années" Le Cid, Pierre Corneille, Don Rodrigue parlant au Comte
                                                      22 janvier 2018 à 12:34:19

                                                      Vous devriez faire une fonction "main" qui utilise vos classes, pour vérifier que leur utilisation est logique pour une personne externe à l'implémentation de ces classes.

                                                      Le lien entre les classes et leur arités ne sont pas triviales, avec une vraie fonction "main", ça permettrait de voir les problèmes plus simplement.

                                                      Beaucoup trop d'include dans "wlan.h". Il faut mettre le strict minimum dans le .h, quitte à en ajouter dans le .cpp.

                                                      "interfaces.h" et "interface.h", WTF !!!

                                                      "windows.h", toujours en premier, mais dans le .cpp.

                                                      Pas de "#pragma warning" pour ne pas faire les cast nécessaires, SVP !!!

                                                      La saisie des valeurs depuis la console ne devrait pas être dans le constructeur de Wlan mais passer en paramètres du constructeur. Ainsi, votre classe sera utilisable dans n'importe quel type de projet (console, GUI, Service Windows, etc...).

                                                      N'utilisez pas "std::cerr" dans vos classes, lancez des exceptions. Cela permet d'utiliser vos classes partout, et bien plus simplement.

                                                      Ne rendez pas les "builders" publiques, les "friend" sont fait pour ça. ;-)

                                                      Utilisez le débogueur pour débuguer, pas du code en plus donc des bugs potentiellement en plus.

                                                      C'est quoi la valeur ajoutée de la classe "Interfaces" ???

                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                      Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                                                        23 janvier 2018 à 10:17:52

                                                        Bonjour,

                                                        > Vous devriez faire une fonction "main" qui utilise vos classes, pour vérifier que leur utilisation est logique pour une personne externe à l'implémentation de ces classes.

                                                        Le lien entre les classes et leur arités ne sont pas triviales, avec une vraie fonction "main", ça permettrait de voir les problèmes plus simplement.

                                                        "Le lien entre les classes et leur arités ne sont pas triviales", waouh, j'ai mit un peu de temps a comprendre cette phrase...

                                                        J'ai fait une fonction main que j'utilise avec des valeurs "en dur", le code est à la fin.

                                                        > Beaucoup trop d'include dans "wlan.h". Il faut mettre le strict minimum dans le .h, quitte à en ajouter dans le .cpp.

                                                        "windows.h", toujours en premier, mais dans le .cpp.

                                                        Pas de "#pragma warning" pour ne pas faire les cast nécessaires, SVP !!!

                                                        La saisie des valeurs depuis la console ne devrait pas être dans le constructeur de Wlan mais passer en paramètres du constructeur. Ainsi, votre classe sera utilisable dans n'importe quel type de projet (console, GUI, Service Windows, etc...).

                                                        Corrigé aussi, le code à la fin.

                                                        > "interfaces.h" et "interface.h", WTF !!!

                                                        alors... la classe Interfaces représente l'intégralité des interfaces wifi détectées, et Interface représente une interface en particulier, créerInterfaces de la classe Interfaces retourne un tableau de pointeurs sur des objets de type Interface. Les noms sont peut être un peu compliqués mais de toutes façon, l'utilisateur de doit même pas être au courant de leur existence (je commence à comprendre le principe ;) )

                                                        >Ne rendez pas les "builders" publiques, les "friend" sont fait pour ça. ;-)

                                                        Tous les constructeurs doivent donc être privés avec des liens d'amitiés entre les classes ?

                                                        Je ne sais pas trop comment m'organiser, auriez-vous une piste ?

                                                        >Utilisez le débogueur pour débuguer, pas du code en plus donc des bugs potentiellement en plus.

                                                        Vous devez parler du

                                                        	std::cout << SSID << " " << password << std::endl; //uniquement pour le débug

                                                        dans profil.cpp, je l'enlève, j'ai décidément du mal a utiliser le débogueur...


                                                        >C'est quoi la valeur ajoutée de la classe "Interfaces" ???

                                                        la valeur ajoutée de la classe Interfaces ? Je n'ai pas bien compris ce qu'est la valeur ajoutée d'une classe...

                                                        > N'utilisez pas "std::cerr" dans vos classes, lancez des exceptions. Cela permet d'utiliser vos classes partout, et bien plus simplement.

                                                        Je lance une exception, et je la traite comment ?

                                                        Je dois bien afficher un message d'erreur !

                                                        Bon, le code :

                                                        Wifi.cpp

                                                        #include "profil.h"
                                                        #include "interface.h"
                                                        #include "interfaces.h"
                                                        #include "wlan.h"
                                                        
                                                        int main()
                                                        {
                                                        	Wlan wlan("test", "test");
                                                        	return 0;
                                                        }

                                                        wlan.h

                                                        #pragma once
                                                        #include <memory>
                                                        #include <vector>
                                                        #include "profil.h"
                                                        #include "interface.h"
                                                        #include "interfaces.h"
                                                        
                                                        class Wlan
                                                        {
                                                        	std::unique_ptr<Profile> profile;
                                                        	std::vector<std::unique_ptr<Interface>> interfaces;
                                                        public:
                                                        	Wlan(std::string SSID, std::string password);
                                                        };

                                                        wlan.cpp

                                                        #include "wlan.h"
                                                        #include <Windows.h>
                                                        
                                                        Wlan::Wlan(std::string SSID, std::string password)
                                                        {
                                                        	bool profilCree = false;
                                                        	interfaces = Interfaces::creerInterfaces();
                                                        	try
                                                        	{
                                                        		for (int i(0); i < (int)interfaces.size(); i++)
                                                        		{
                                                        			if (interfaces[i]->nomInterface == SSID)//si le nom du réseau saisi est trouvé dans la liste on créé un profile
                                                        			{
                                                        				profile = Profile::createProfile(SSID, password);
                                                        				profilCree = true;
                                                        				break;
                                                        			}
                                                        		}
                                                        		if (profilCree == false)//si le profil n'est pas créé car le reseau passé en paramètre n'est pas trouvé dans la liste
                                                        		{
                                                        			throw std::string("ERREUR : le réseau spécifié est introuvable, le programme va s'arreter.");
                                                        		}
                                                        	}
                                                        	catch (std::string const& e)
                                                        	{
                                                        		exit(EXIT_FAILURE);
                                                        	}
                                                        }

                                                        profil.h

                                                        #pragma once
                                                        #include <memory>
                                                        #include <string>
                                                        
                                                        class Profile
                                                        {
                                                        	friend class Wlan;
                                                        	Profile();
                                                        public:
                                                        	static std::unique_ptr<Profile> createProfile(std::string SSID, std::string password);
                                                        };

                                                        profil.cpp

                                                        #include <string>
                                                        #include <iostream>
                                                        #include "profil.h"
                                                        
                                                        
                                                        std::unique_ptr<Profile> Profile::createProfile(std::string SSID, std::string password)
                                                        {
                                                        	return std::unique_ptr<Profile>();
                                                        }
                                                        


                                                        interfaces.h

                                                        #pragma once
                                                        #include <vector>
                                                        #include <memory>
                                                        #include "interface.h"
                                                        class Interfaces
                                                        {
                                                        public:
                                                        	Interfaces();
                                                        	static std::vector<std::unique_ptr<Interface>> creerInterfaces();
                                                        };

                                                        interfaces.cpp

                                                        #include "interfaces.h"
                                                        
                                                        Interfaces::Interfaces()
                                                        {
                                                        }
                                                        
                                                        std::vector<std::unique_ptr<Interface>> Interfaces::creerInterfaces()
                                                        {
                                                        	return std::vector<std::unique_ptr<Interface>>();
                                                        }
                                                        

                                                        interface.h

                                                        #pragma once
                                                        #include <memory>
                                                        #include <string>
                                                        
                                                        class Interface
                                                        {
                                                        	friend class Wlan;
                                                        	Interface();
                                                        	std::string nomInterface;
                                                        public:
                                                        	static std::unique_ptr<Interface> createInterface();
                                                        };

                                                        interface.cpp

                                                        #include "interface.h"
                                                        
                                                        Interface::Interface()
                                                        {
                                                        }
                                                        
                                                        std::unique_ptr<Interface> Interface::createInterface()
                                                        {
                                                        	return std::unique_ptr<Interface>();
                                                        }

                                                        Bien à vous,

                                                        Raphael



                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                        "La valeur n'attend point le nombre des années" Le Cid, Pierre Corneille, Don Rodrigue parlant au Comte
                                                          23 janvier 2018 à 12:07:37

                                                          >J'ai fait une fonction main que j'utilise avec des valeurs "en dur", le code est à la fin.

                                                          Bien.

                                                          Tu devrais être un peu plus ambitieux, mais c'est un bon début pour un POC (Proof Of Concept).

                                                          >alors... la classe Interfaces représente l'intégralité des interfaces wifi détectées,

                                                          C'est bien ce que je craignais.

                                                          Maintenant, justifies moi un constructeur de la classe "Interfaces". :-°

                                                          Non, "Interfaces" n'a aucun utilité, ou pas encore.

                                                          Transfères la ligne 9 de "Interfaces.h" dans "Interface.h" et les lignes 7 à 10 d'"Interfaces.cpp" dans "Interface.cpp", en supprimant le "s" dans le nom de la classe.

                                                          Cela transfèrera la méthode statique de la classe "Interfaces" à la classe "Interface", là où elle devrait être.

                                                          >Tous les constructeurs doivent donc être privés avec des liens d'amitiés entre les classes ?

                                                          Ça dépend des classes et des fonctionnalités que vous voulez offrir au code client de votre bibliothèque.

                                                          Mais, on peut, dans un premier temps, tout mettre en publique puis verrouiller plus tard.

                                                          C'est pas une super pratique mais si on fait le travail de verrouillage rapidement, c'est pas trop grave.

                                                          Ici, c'est juste pour pas perdre trop de temps avec ce détail avant d'avoir un truc qui tournicote.

                                                          >la valeur ajoutée de la classe Interfaces ? Je n'ai pas bien compris ce qu'est la valeur ajoutée d'une classe...

                                                          Vous gagnez quoi comme fonctionnalité d'avoir une classe "Interfaces" en plus d'une classe "Interface" ?

                                                          Aucune, suffit de mettre la méthode statique dans la classe "Interface" et c'estplus "logique".

                                                          >Je lance une exception, et je la traite comment ?

                                                          Exactement comme dans les lignes 24 à 27 de "wlan.cpp" mais dans le code du client qui est le seul à savoir comment traiter ces erreurs  et non votre bibliothèque.

                                                          Donc on oublie le "exit" bien crade de la ligne 26 de "wlan.cpp". Si le code client veut faire autre chose, comme prévenir l'utilisateur ou réinitialiser la carte Wifi, vous lui avez coupé toutes possibilités de correctement gérer le problème.

                                                          >Je dois bien afficher un message d'erreur !

                                                          C'est au code client de faire ce choix, ou pas, pas à vos classes/bibliothèques.

                                                          Dans "Wifi.cpp", vous n'utilisez pas de "Profil" ou d'Interface, supprimer les includes ligne 1 à 3.

                                                          Dans "Wlan.h", je comprends pas pourquoi vous voulez garder toutes les Interfaces comme champ, seule celle ayant le bon SSID devrait être conservée, je pense.

                                                          "ProfilCree" est une variable superfétatoire, vous devriez tester la valeur de profile.

                                                          "Throwez" des exceptions plutôt que des std::string. Ça simplifiera la gestion des erreurs par le code client.

                                                          Dans "Wlan.cpp" :"windows.h", toujours en premier (BIS)

                                                          Maintenant, essayez de commencer à utiliser les primitives Win32 dans vos méthodes pour faire le travail.

                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                          Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.
                                                            24 janvier 2018 à 22:04:17

                                                            Bonjour !

                                                            J'essaye d'utiliser les fonctions Win32 mais j'ai deux questions concernant les exceptions : pour l'exception que je lance si aucun wifi n'est trouvé, je ne la gère pas ? je me contente de la lancer et c'est l'utilisateur qui s'occupera de l'attraper et de la gérer ?

                                                            Et ensuite je dois lancer des exceptions (je parle ici de la classe) mais je lance directement une exception on je créé une classe qui hérite de exception pour avoir mon propre type d'exception ?

                                                            • Partager sur Facebook
                                                            • Partager sur Twitter
                                                            "La valeur n'attend point le nombre des années" Le Cid, Pierre Corneille, Don Rodrigue parlant au Comte
                                                              25 janvier 2018 à 10:28:43

                                                              >pour l'exception que je lance si aucun wifi n'est trouvé, je ne la gère pas ?

                                                              Si ta bibliothèque ne peut rien faire, que veux-tu "gérer" ?

                                                              >je me contente de la lancer et c'est l'utilisateur qui s'occupera de l'attraper

                                                              Si tu parles du développeur en tant qu'utilisateur, oui, c'est à lui de présenter le problème à l'utilisateur final de l'application qu'il développe.

                                                              > et de la gérer ?

                                                              S'il veut (le développeur de l'application), par exemple, réinitialiser le Wifi, oui il catche l'exception correspondant à l'absence de Wifi et fait ce qu'il semble nécessaire à ces yeux.

                                                              >mais je lance directement une exception on je créé une classe qui hérite de exception pour avoir mon propre type d'exception ?

                                                              Comme le développeur de l'application ne peut pas gérer tous les types d'exception, il vaudrait mieux qui tu crées ta propre classe d'exception, voir une arborescence d'exception avec une classe mère pour toutes celles que tu comptes lancer. Cela simplifiera grandement l'usage de tes composants avec d'autres dans une même application.

                                                              • Partager sur Facebook
                                                              • Partager sur Twitter
                                                              Je recherche un CDI/CDD/mission freelance comme Architecte Logiciel/ Expert Technique sur technologies Microsoft.

                                                              lister les wifis disponibles et s'y connecter

                                                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                              • Editeur
                                                              • Markdown