web-dev-qa-db-fra.com

Lors de l'écriture de code orienté objet, dois-je toujours suivre un modèle de conception?

Existe-t-il un modèle de conception envisageable pour tout programme orienté objet? Je pose cette question car récemment j'ai vu une implémentation d'une classe Door avec un Lock. Cela faisait partie d'un test et la réponse a dit que le code suit le modèle Null Object:

class Lock
{
public:
    virtual void close() = 0;
    virtual void open() = 0;
    virtual bool is_open() const = 0;
    virtual ~Lock() { }
};

class DummyLock
    : public Lock
{
private:
    DummyLock();
    DummyLock(const DummyLock&) = delete;
    DummyLock& operator=(const DummyLock&) = delete;

private:
    void close() { }
    void open() { }
    bool is_open() const { return true; }

public:
    static DummyLock m_instance;
};

class Door
{
public:
    Door() : m_lock(DummyLock::m_instance) { }
    Door(Lock &lock) : m_lock(lock) { }

public:
    Lock& get_lock() const { return m_lock; }

private:
    Lock &m_lock;
};

Cela m'a fait penser: ce code suit un bon modèle de conception même si la description est si simple (cette classe conçoit une classe de porte avec un verrou), donc si j'écris du code plus complexe, devrait-il toujours = être un modèle de conception que je suis?

36
user2030677

devrait-il toujours y avoir un modèle de conception que je suis?

Cher Dieu NON!

Je veux dire, vous pouvez aller de l'avant et dire que tout code aléatoire suit un modèle XYZ aléatoire, mais ce n'est pas plus utile que moi prétendant être le roi de ma chaise d'ordinateur. Personne d'autre ne sait vraiment ce que cela signifie et même ceux qui ne respecteront pas exactement ma demande.

Les modèles de conception sont un outil de communication qui permet aux programmeurs de dire aux autres programmeurs ce qui a été fait ou ce qui devrait être fait sans passer beaucoup de temps à se répéter. Et comme ce sont des choses qui reviennent plusieurs fois, ce sont des concepts utiles pour que les programmeurs apprennent "hé, faire XYZ semble toujours venir parce que c'est bon/utile".

Ils ne remplacent pas le besoin pour vous de penser par vous-même, d'adapter les modèles pour le problème unique devant vous , ou pour gérer toutes les choses inévitables qui ne rentrent pas dans les seaux Nice.

144
Telastyn

Non.

C'est ce que le Gang of Four (qui a à l'origine popularisé les modèles de conception) avait à dire à ce sujet dans leur livre :

"Aucune discussion sur l'utilisation des modèles de conception ne serait complète sans quelques mots sur la manière de ne pas les utiliser. Les modèles de conception ne doivent pas être appliqués sans discernement. Souvent ils atteignent flexibilité et variabilité en introduisant des niveaux d'indirection supplémentaires, ce qui peut compliquer une conception et/ou vous coûter des performances. Un modèle de conception ne doit être appliqué que lorsque la flexibilité qu'il offre est réellement nécessaire. "

L'exemple que vous montrez ne fait en fait pas grand-chose (je ne pense pas qu'il était destiné à, je pense que c'était juste destiné à être un exemple). En soi, il n'a pas besoin du modèle d'objet nul. Dans le contexte d'un programme plus vaste, il se pourrait.

La mauvaise approche suppose que ce n'est pas parce qu'il a été qualifié de "modèle de conception" qu'il doit être bon, puis de rechercher plus d'endroits pour entasser plus de modèles. Utilisez-les lorsqu'ils correspondent au programme et résolvez réellement un problème pour vous.

38
Michael Shaw

si j'écris du code plus complexe, devrait-il toujours y avoir un modèle de conception que je suis?

Non. Les modèles de conception ne sont que cela: modèles dans les relations entre les objets. En d'autres termes, les relations qui sont utilisées et réutilisées assez souvent pour que quelqu'un dise "Hé, nous semblons faire beaucoup de choses, donnons-lui un nom." La liste des modèles de conception n'a pas été déterminée d'un seul coup au début de OOP puis transmis par GOF ! Ils ont été découverts et finalement documentés, puis popularisés par le livre.

Cela dit, une grande partie de l'avantage des modèles de conception est qu'ils facilitent la réflexion sur la conception de logiciels à un niveau supérieur. Ils vous permettent d'éviter de vous soucier des détails de la mise en œuvre et de réfléchir davantage à la vue d'ensemble. En ce sens, ils vous libèrent de la minutie, mais ils peuvent également vous limiter de la même manière que la façon dont vous vous exprimez peut être limitée par les mots que vous connaissez. Ainsi, il peut arriver un moment où il y a est un modèle de conception pour la plupart de ce que vous faites simplement parce que les modèles que vous connaissez sont les termes dans lesquels vous pensez. Gardez les yeux ouverts pour les cas où vous pourriez abuser d'un schéma et où vous devrez peut-être réfléchir plus profondément à de meilleures façons de faire les choses.

De plus, sachez que dans la pratique, vous ne faites souvent pas implémenter un modèle de conception donné au lieu de reconnaître le modèle dans du code existant, comme un framework d'objet. Connaître les modèles de conception courants facilite beaucoup la façon dont un framework est destiné à être utilisé car vous pouvez voir les relations entre les classes en termes que vous comprenez déjà.

29
Caleb

Les modèles de conception ont deux avantages

  1. Ils sont faciles à décrire aux autres développeurs, car les gens sont généralement d'accord sur les modèles
  2. Ils ont tendance à être battus de façon assez réfléchie par nos prédécesseurs, de sorte que leurs forces et leurs faiblesses sont bien comprises.

Les objectifs de chaque programme devraient être

  1. Ça marche. Il doit faire quel que soit l'objectif final, ou peu importe le nombre de modèles de conception que vous utilisez. OO les modèles de conception facilitent la division du problème en bits faciles à comprendre, il est donc plus facile de prouver qu'il fonctionne.
  2. Ç'est facile a lire. C'est là que les modèles de conception sont agréables. Les problèmes OO qu'ils résolvent sont compliqués. Si vous les résolvez de manière "standard", c'est plus facile pour le prochain développeur.
  3. C'est facile à cultiver. Près de 0 programmes modernes se terminent là où tout le monde les avait prévus. Chaque programme se développe après sa sortie initiale. OO les modèles sont connus pour être curieusement bons en croissance.

Cela étant dit, notez que chaque référence aux modèles de conception OO est "ils sont juste bons au travail." Ils ne sont pas parfaits, mais ils remplissent très efficacement un créneau. Utilisez-les quand ils travaillent, évitez-les quand ils ne le font pas.

À titre d'exemple, de "code complexe", comme vous l'avez mentionné dans votre question, prenez un langage de script que j'ai écrit. La plupart est OO avec des modèles de conception partout. Cependant, quand il s'agissait d'écrire le ramasse-miettes, j'ai abandonné sans ménagement toutes les prétentions d'OO, car les choses particulières que je devais faire étaient mieux modélisées comme il n'y a pas de modèle OO dans le tout jusqu'à l'écriture des finaliseurs, où encore une fois OO a commencé à être un modèle utile à nouveau. Sans aucune pompe ni circonstance, le code est soudainement revenu en utilisant à nouveau les techniques OO.

tilisez des modèles de conception chaque fois qu'ils améliorent votre produit; évitez-les lorsqu'ils aggravent votre produit.

10
Cort Ammon

Je vais inverser un peu la tendance, car la réponse est plus subtile que ne le laissent entendre les autres réponses. Chaque classe que vous écrivez ne devrait pas utiliser de modèle de conception, mais la plupart non triviale programmes que vous écrivez devrait probablement.

Un programme non trivial sans aucun modèle de conception indique:

  • Votre programme est si unique qu'aucune partie de celui-ci n'est similaire aux problèmes courants rencontrés par les programmeurs auparavant. Ou
  • Votre programme contient ces problèmes courants, mais vous les avez résolus d'une meilleure manière que personne n'avait pensé auparavant.

Les deux scénarios sont hautement improbables, sans infraction.

Cela ne signifie pas que le modèle de conception doit guider votre conception, ou que vous devez en insérer sans discernement, car vous pensez qu'il ne sera pas bon si vous ne le faites pas. Le mauvais modèle de conception est pire qu’aucun.

Cela signifie que vous devriez considérer le manque de modèles de conception dans votre programme global comme une odeur de code. Quelque chose qui vous fait jeter un deuxième coup d'œil et réévaluer si votre conception ne pouvait pas être plus propre. Si, à ce stade, vous décidez de laisser les modèles de conception en dehors d'un programme, cela devrait être une décision délibérée et éclairée, pas un hasard.

Par exemple, vous ne dites pas: "J'ai besoin de modéliser une porte et une serrure, quel modèle de conception dois-je utiliser?" Cependant, si vous l'avez conçu en premier sans utiliser de modèles de conception, cela devrait vous inciter ensuite à dire quelque chose comme: "J'ai énormément de vérifications nulles dans ce code, je me demande s'il existe un modèle de conception qui pourrait aider à les gérer."

Regarde la différence? C'est une distinction subtile mais importante.

5
Karl Bielefeldt

Question cassée. Permettez-moi de vous donner une nouvelle définition du modèle de conception qui annulerait beaucoup de dommages libérés par GoF: n modèle de conception est une bonne pratique de codage. C'est ça.

Tout module raisonnablement complexe comportera plusieurs modèles de conception. Chaque fois que vous mettez en cache, c'est probablement un modèle de poids mouche, mais je ne révoquerai pas votre diplôme en programmation si vous ne l'appelez pas ainsi. Chaque fois que vous avez un rappel, vous êtes dans une sorte d'événement/incendie/rappel. etc. Si vous avez le mot "statique", vous avez un singleton. Si vous avez un constructeur statique, vous avez un modèle d'usine. Si une ressource est transmise à votre module, vous utilisez l'injection de dépendances.

"Motif de conception" est un terme brisé mal popularisé par le GoF, qui donne l'impression que tous les motifs sont au même niveau ou vous devriez utiliser le médecin recommandé 3 à 5 par classe. Chaque fois que vous faites quelque chose de bien que quelqu'un d'autre a bien fait, c'est un modèle de conception. Une for(;;) est un modèle commun utilisé pour représenter une boucle infinie, par exemple.

Vous ne devriez pas essayer d'apprendre un tas de modèles de conception. Les connaissances en programmation ne sont pas indexées par les modèles de conception! Plutôt vous devez apprendre à écrire du bon code en lisant des livres, des blogs et en assistant à des conférences dans votre domaine. Par exemple, si vous utilisez déjà l'injection de dépendance mais que vous ne l'avez tout simplement pas étiqueté, vous pourriez bénéficier de toujours en utilisant DI ou en utilisant un framework IoC. Ou si vous avez du mal à coder correctement dans les événements et les rappels, allez apprendre Haskell afin que vous soyez familier avec les modèles de conception fonctionnels et cela devient facile.

Et si toute votre classe se lit comme une grande chose que quelqu'un d'autre a bien fait, pourquoi réinventez-vous la roue? Utilisez simplement leurs trucs.

4
djechlin

Lorsque j'écris du code, je ne prévois pas d'utiliser délibérément autant de modèles de conception que possible. Mais, je suppose, inconsciemment, lorsque je rencontre un problème de codage, l'un des modèles de conception semble correspondre, et je l'utilise. Et parfois, rien ne va. Ce qui est plus important pour moi, c'est d'écrire du code qui fait le travail et qui est facile à maintenir et à développer.

Voici un article sur l'application des principes OOD à l'aide de modèles de conception, et il contient également des exemples de code (en C++). Il montre comment et quand appliquer certains des modèles de conception pour écrire du code propre.

0
rosewater

Les modèles sont des solutions courantes aux problèmes courants. Nous suivons toujours certains modèles, les modèles de GoF s'adressent aux plus récurrents. Cela, pour avoir une compréhension et une approche partagées connues des ingénieurs logiciels.

Cela dit, ma réponse est non, mais oui, vous suivez toujours votre propre schéma. Comme le GoF le dit à juste titre -

Le modèle d'une personne est le bloc de construction primitif d'une autre personne.

Très bonne citation.

0
Syed Priom

Vous devez toujours suivre les principes de conception OO (par exemple, modularité, masquage des informations, cohésion élevée, etc.). Les modèles de conception sont une niche relativement raffinée de OO principes de conception, surtout si vous considérez le principe KISS .

Les modèles sont des solutions aux problèmes de conception courants. Ces problèmes proviennent de l'un des deux endroits (ou d'un mélange des deux): l'espace des problèmes (par exemple, un logiciel pour gérer les ressources humaines dans une entreprise) et l'espace de solution . Un programme OO est une instance dans l'espace de solution (par exemple, l'une des nombreuses façons de concevoir un programme OO pour faciliter la gestion des RH).

Ce n'est pas si facile de savoir quand utiliser un motif. Certains modèles sont de bas niveau, plus proches du codage et de l'espace de solution (par exemple, Singleton, objet Null, Iterator). D'autres sont motivés par les exigences de l'espace du problème (par exemple, modèle de commande pour prendre en charge annuler/rétablir, stratégie pour prendre en charge plusieurs types de fichiers d'entrée/sortie).

De nombreux modèles proviennent de la nécessité de prendre en charge des variantes du logiciel à l'avenir. Si vous n'avez jamais besoin de faire ces variations, un motif peut être sur-conçu. Un exemple serait d'utiliser le modèle d'adaptateur pour travailler avec la base de données RH externe existante. Vous décidez d'appliquer Adapter car la base de données actuelle fonctionne avec Oracle et vous souhaiterez peut-être prendre en charge NoSQL à l'avenir. Si NoSQL ne vient jamais dans votre organisation, ce code d'adaptateur pourrait très bien être inutile. Voir YAGNI . La prise en charge des variations qui ne se produisent jamais utilise à mauvais escient un modèle de conception.

0
Fuhrmanator