• [^] # Re: Framework web

    Posté par (site web personnel, Mastodon) . En réponse à la dépêche Première beta de POCHE 1.0 disponible. Évalué à 2.

    Ils sont indispensables, puisque leur absence entraîne une impossibilité d'encapsuler. L'encapsulation, c'est rendre étanche l'état interne d'un système de ces clients, et de fournir aux clients une interface de manipulation.

    Bien évidement, les modificateur de visibilité ne garantissent pas l'encapsulation. Nombreux sont les imbéciles à générer automatiquement des getter qui exposent induement un composant interne à l'extérieur. Comme par exemple, le dernier getter proposé dans cet exemple :

    class State
    {
     /* ... */
    } /* class State */;
    class BlackBox
    {
     class Impl;
     std::unique_ptr<Impl> p_impl;
     public:
     BlackBox();
     BlackBox(BlackBox const &);
     BlackBox & operator=(BlackBox const &);
     // Une copie de l'état interne de l'objet
     State const state() const;
     // Optimisation du précédent, mais avec une brèche qui peut mener à la
     // manipulation de l'état interne de l'objet
     State const & state() const;
     // Une exposition directe de l'état interne de l'objet
     State & state();
    } /* class BlackBox */;

    On voit bien que dans le premier, la manipulation de l'état interne de l'objet n'est pas possible sans reverse engineering. Dans le second cas, un const_cast est possible, c'est parfois ça le coût de l'optimisation. Dans le dernier cas, c'est la fête du slip : il n'est plus possible de changer d'état sans effet de bord. Sauf à limiter fortement la conception interne de la classe, et c'est là qu'on voit que l'encapsulation n'est plus.

    Tu me diras qu'en Python, on s'en fout, on manipule des références.

    # abstract
    class State(object):
     pass
    class InitState(State):
     message = 'Initial'
    class TermState(State):
     message = 'Terminal'
    class BlackBox(object):
     def __init__(self):
     self._state = InitState()
     def state(self):
     return self._state
     def next_state(self):
     if isinstance(self._state, TermState):
     raise BaseException('Mais euh!')
     self._state = TermState()
    def client():
     bb = BlackBox()
     # Aquisition d'une reference sur l'etat interne de l'objet (note que ce commentaire est
     # errone)
     current_test = bb.state()
     while current_test.message is 'Initial':
     bb.next_state()
    client()

    Au temps pour les références et leur usage incorrect... Alors oui, il est possible de faire la même connerie en C++, conserver l'état et le réutilisé plus tard. Mais la grosse différence, c'est qu'en C++ tu sais que tu acquiert une copie, et que donc c'est copie a une durée de vie courte.

    C'est pour ce genre de conneries que j'aime l'encapsulation, l'hermétisme des systèmes et la rigueur.