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


37

Existe-t-il un modèle de conception concevable pour tout programme orienté objet? Je demande cela parce que récemment j'ai vu une implémentation d'une Doorclasse avec un Lock. Cela faisait partie d'un test et la réponse indiquait que le code suivait le modèle d'objet nul:

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 un code plus complexe, devrait-il toujours y avoir un modèle de conception suis-je?



51
Pensez-vous que vous pourriez parler entièrement dans les idiomes? Non? Ensuite, vous ne devriez pas construire vos programmes en combinant des modèles de conception.
Kilian Foth

4
Dans votre exemple, le modèle d'objet Null n'est ajouté qu'à des fins académiques, il n'introduit pas "une bonne conception" dans ce code.
Doc Brown

4
@djechlin: en d'autres termes, utilisez le modèle de conception "deux mots" :)
Michael Shaw

11
Le problème est que trop de gens croient que les modèles de conception se substituent à la pensée et à l'expérience (ce qui implique un certain nombre d'essais et d'erreurs). Vous ne pouvez pas prendre un livre plein de modèles de conception et les assembler, comme Tinker Toys, pour produire une application d'une taille et d'une complexité non négligeables, et d'une qualité correcte. Même les programmeurs expérimentés doivent souvent essayer deux ou trois modèles avant de trouver celui qui fonctionne.
Daniel R Hicks

Réponses:


143

devrait-il toujours y avoir un motif de conception que je suis?

Cher Dieu, non!

Je veux dire, vous pouvez continuer et dire que tout code aléatoire suit un motif XYZ aléatoire, mais ce n'est pas plus utile que de prétendre être le roi de mon fauteuil d'ordinateur. Personne d'autre ne sait vraiment ce que cela signifie et même ceux qui le font ne respecteront pas exactement ce que je prétends.

Les modèles de conception sont un outil de communication permettant aux programmeurs de dire aux autres programmeurs ce qui a été fait ou ce qui devrait être fait sans perdre beaucoup de temps à se répéter. Et comme ce sont des choses qui reviennent souvent, ce sont des concepts utiles pour les programmeurs: "Hé, créer XYZ semble toujours apparaître parce que c'est bon / utile".

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


5
Votre premier paragraphe fait partie de ma réponse. Quelque chose devient un motif quand il se répète. S'il est répété suffisamment de fois pour nécessiter une communication, il s'agit d'un motif qui bénéficie d'un nom. Certains font même valoir qu'un motif ne se développe que parce qu'il manque une partie de l'abstraction. Poursuite de modèles est la voie à l'infamie en tant que membre du culte Cargo vantée.
Magus

11
@Cerad: Bien sûr, tant que vous promettez de ne pas écrire les classes de Dieu aussi!
Yatima2975

9
John Doe - ingénieur technique, code générique Monkey et roi de sa chaise d'ordinateur
hjk

1
On peut soutenir que la conception devrait utiliser des modèles, le cas échéant, et que les classes devraient être nommées comme telles. Ils sont un outil important. Avoir peur de the_cult(TM) est tout aussi dangereux.
Gusdor

25
Très bonne réponse! Ma seule critique est que le "Dear God NO!" n'est pas assez grand.
tobyink

37

Non.

Voici ce que la bande des quatre (qui avait initialement popularisé les modèles de conception) en avait parlé dans son livre :

"Aucune discussion sur la façon d'utiliser les modèles de conception ne serait complète sans quelques mots sur la façon de ne pas les utiliser. Les modèles de conception ne doivent pas être appliqués indifféremment. Ils permettent souvent une flexibilité et une variabilité en introduisant des niveaux supplémentaires d'indirection, ce qui peut compliquer la conception et / ou vous coûtent quelques 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 pas grand-chose (je ne pense pas que c’était censé être, c’était seulement un exemple). En soi, il n'a pas besoin du modèle d'objet null. Dans le contexte d'un programme plus vaste, cela se pourrait.

La mauvaise approche consiste à supposer que, simplement parce que le label a été qualifié de "modèle de conception", il doit être bon, puis à chercher davantage d’endroits pour y ajouter plus de modèles. Utilisez-les lorsqu'ils correspondent au programme et résolvent réellement un problème pour vous.


7
Le livre intitulé Design Patterns: Eléments d'un logiciel orienté objet réutilisable de Erich Gamma, Richard Helm, Ralph Johnson et John Vlissides.
developerwjk

4
+1 Pour citer réellement la source des modèles de conception.
Pharap

29

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

Les modèles de conception ne sont que cela: des 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 le faire beaucoup, donnons-lui un nom." La liste des modèles de conception n’a pas été déterminée en une fois au début de la programmation orientée objet, puis transmise par GOF ! Ils ont été découverts et finalement documentés, puis popularisés par le livre.

Cela dit, l’un des avantages des modèles de conception est qu’ils facilitent la réflexion sur la conception de logiciels à un niveau supérieur. Ils vous permettent de ne pas vous soucier des détails de la mise en œuvre et de réfléchir davantage à la situation dans son 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. Il se peut donc que, à un moment donné, il existe un modèle de conception pour la plupart de vos activités simplement parce que les modèles que vous connaissez sont les termes auxquels vous pensez. Gardez l'oeil ouvert pour les cas où vous pourriez abuser d'un modèle et où vous pourriez avoir besoin de réfléchir plus profondément à de meilleures façons de faire les choses.

En outre, se rendre compte que , dans la pratique , vous souvent ne pas mettre en œuvre un modèle de conception donnée afin de reconnaître autant que le modèle dans un code existant, comme un cadre d'objet. En connaissant les modèles de conception courants, il est beaucoup plus facile d'apprendre comment un framework doit être utilisé, car vous pouvez voir les relations entre les classes dans des termes que vous comprenez déjà.


10

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 généralement été malmenés 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. Quel que soit le but final recherché, peu importe le nombre de modèles de conception que vous utilisez. Les modèles de conception OO facilitent la résolution du problème en bits faciles à comprendre, il est donc plus facile de prouver que cela fonctionne.
  2. Ç'est facile a lire. C’est là que les modèles de design sont agréables Les problèmes d'OO qu'ils résolvent sont compliqués. Si vous les résolvez de manière "standard", c'est plus facile pour le développeur suivant.
  3. Il est facile de grandir. Presque 0 programmes modernes se terminent là où tout le monde les prévoyait. Chaque programme grandit après sa sortie initiale. Les modèles OO sont connus pour être curieusement bons pour la croissance.

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

Comme exemple de "code complexe", comme vous l'avez mentionné dans votre question, prenons un langage de script que j'ai écrit. Il s’agit en grande partie de OO avec des motifs partout. Cependant, quand il s’agissait d’écrire le ramasse-miettes, j’abandonnai sans ménagement tous les faux semblants de OO, parce que les choses que je devais faire étaient mieux modélisées comme du bon vieux matraque. Jusqu'au moment de l'écriture des finaliseurs, il n'existait pas de modèle OO dans lequel tout redevenait un modèle utile. Sans aucune pompe ni circonstance, le code est soudainement revenu à l'utilisation de techniques OO.

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


2
Je pense que la dernière phrase devrait être en haut en gras ou en résumé.
Pharap

5

J'écarterai un peu la tendance, car la réponse est plus subtile que les autres réponses ne laissent présager. Chaque classe que vous écrivez ne doit pas employer de modèle de conception, mais la plupart des programmes non triviaux que vous écrivez le devraient probablement.

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

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

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

Cela ne signifie pas que le modèle de conception doit orienter votre conception, ou que vous devez en insérer un sans distinction, car vous pensez qu'il sera mauvais si vous ne le faites pas. Le mauvais modèle est pire que rien.

Cela signifie que vous devriez considérer l'absence de modèles de conception dans l'ensemble de votre programme comme une odeur de code. Quelque chose qui vous fait jeter un deuxième coup d'oeil et réévaluer si votre conception ne pourrait pas être plus propre. Si, à ce stade, vous décidez de ne pas utiliser de modèle de conception dans un programme, vous devez choisir délibérément et en connaissance de cause et non pas un hasard.

Par exemple, vous ne dites pas: "Je dois modéliser une porte et une serrure, quel modèle de conception dois-je utiliser?" Cependant, si vous l'avez conçu d'abord sans utiliser de modèles de conception, cela devrait vous inciter ensuite à dire quelque chose comme: "J'ai énormément de contrôles nuls 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
Il y a beaucoup plus de problèmes communs (et leurs solutions communes) qu'il n'y a de modèles de conception. Les modèles de conception constituent un sous-ensemble catalogué de solutions OO courantes - et non l'ensemble de toutes les solutions courantes.
Michael Shaw

1
Pouvez-vous définir ce que vous entendez par «non trivial»? J'avais l'impression que le terme «non trivial» était subjectif.
Pharap

1
C'est subjectif. Je veux dire le genre de programme que vous écririez dans une équipe au travail, nécessitant plusieurs mainteneurs sur une base continue.
Karl Bielefeldt

Si vous avez la chance de voir votre problème par la suite. Null Checks, bien sûr. Des vulnérabilités de sécurité? Autres moyens insidieux que le programme va casser sous maintenance? Des problèmes que seul le prochain ingénieur va découvrir? Beaucoup plus dégueulasse.
Djechlin

"Je dois modéliser une porte et une serrure. Quelle doit être l'interface? Les performances feront-elles partie du contrat? Devrais-je utiliser un service ou une bibliothèque? Comment les ressources seront-elles transférées?" devrait tous être demandé, et vous devriez avoir des réponses qui sont essentiellement considérées comme des modèles de conception.
Djechlin

4

Question brisée. Permettez-moi de vous donner une nouvelle définition du modèle de conception qui annulerait de nombreux dommages émis par le GoF: un 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 motif de poids mouche, mais je ne révoquerai pas votre diplôme en programmation si vous n'appelez pas cela comme ça. Chaque fois que vous avez un rappel, vous êtes dans une sorte de modèle 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épendance.

"Motif de conception" est un terme cassé mal popularisé par le GoF, ce qui donne à penser que tous les motifs sont du même niveau ou que 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 . A for(;;)est un motif 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! Vous devriez plutôt apprendre à rédiger un bon code en lisant des livres, des blogs et en assistant à des conférences dans votre domaine. Par exemple, si vous utilisez déjà une injection de dépendance mais que vous ne l'avez simplement pas étiquetée, vous pouvez toujours utiliser DI ou un framework IoC. Ou si vous avez du mal à coder correctement les événements et les rappels, allez apprendre Haskell afin de vous familiariser 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 faite, pourquoi réinventez-vous la roue? Il suffit d'utiliser leurs affaires.


2
En quelle langue est for(;;)idiomatique? Ce n'est probablement pas le meilleur exemple de ce que quelqu'un a "bien".
Telastyn

1
@Telastyn C, C ++, Java, Javascript, C #.
Djechlin

2
Je ne l' ai jamais vu quelqu'un préfère que plus while(true)(ou while(1)) en C, C ++, Java ou C # dans mes années de programmation 20+.
Telastyn

1
@Telastyn stackoverflow.com/a/2611744/1339987 fwiw J'ai commencé à préférer while (true) car il me semble plus lisible.
Djechlin

1
J'utilise toujours pour (;;). Aucune raison particulière, je l'ai probablement lu quelque part. J'aime le fait qu'il n'y ait pas de variables ou de constantes impliquées. Quoi qu'il en soit, @Telastyn maintenant que vous avez rencontré quelqu'un .
Ant

0

Vous devez toujours suivre les principes de conception OO (par exemple, la modularité, la dissimulation d'informations, une cohésion élevée, etc.). Les modèles de conception constituent un créneau relativement raffiné des principes de conception OO, en particulier si vous considérez le principe KISS .

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

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 la solution (par exemple, Singleton, Null object, 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 l'annulation / la restauration, Stratégie pour prendre en charge plusieurs types de fichiers d'entrée / sortie).

De nombreux modèles découlent 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 trop design. Un exemple serait d'utiliser le modèle Adapter pour travailler avec la base de données HR 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, le code de cet adaptateur pourrait très bien être inutile. Voir YAGNI . La prise en charge de variations qui ne se produisent jamais n’abuse du motif de conception.


0

Les modèles sont des solutions communes aux problèmes communs. Nous suivons toujours certains modèles, ceux du GoF s’adressant aux plus récurrents. Cela, pour avoir une compréhension partagée et une approche partagée connue des ingénieurs en logiciel.

Cela dit, ma réponse est non, mais oui, vous suivez toujours votre propre modèle. Comme le gouvernement le dit à juste titre.

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

Très bonne citation.


cela ne semble rien offrir de substantiel sur les points soulevés et expliqués dans les 7 réponses précédentes
gnat

Bien. Notez, j'ai fait un point général ... il est applicable à Design Patterns comme une discussion théorique.
Syed Priom

"Ce site vise avant tout à obtenir des réponses . Ce n'est pas un forum de discussion ..." ( tournée )
gnat

J'ai répondu à la question. Merci. Cette conversation se termine ici.
Syed Priom

@gnat c'est quand même bien plus concis.
Djechlin

0

Lorsque j'écris du code, je ne prévois pas délibérément d'utiliser autant de motifs de conception que possible. Mais, je suppose que, inconsciemment, lorsqu'un problème de codage survient, l'un des modèles de conception semble correspondre et je viens de l'utiliser. 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 à faire évoluer.

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


2
Cet article a été écrit hier; êtes-vous affilié au blog? Dans l'affirmative, veuillez divulguer cette affiliation .
Martijn Pieters
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.