Mensonge 2: Le code devrait être conçu autour d'un modèle du monde? [fermé]


23

J'ai récemment lu le billet de blog Three Big Lies et j'ai du mal à justifier le deuxième mensonge, qui est cité ici:

(LIE # 2) LE CODE DEVRAIT ÊTRE CONÇU AUTOUR D'UN MODÈLE DU MONDE

Il n'y a aucune valeur à ce que le code soit une sorte de modèle ou de carte d'un monde imaginaire. Je ne sais pas pourquoi celui-ci est si convaincant pour certains programmeurs, mais il est extrêmement populaire. S'il y a une fusée dans le jeu, soyez assuré qu'il y a une classe "Rocket" (en supposant que le code est C ++) qui contient des données pour exactement une fusée et fait des choses rockety. Sans aucune considération pour ce que la transformation des données est réellement en cours, ou pour la disposition des données. Ou d'ailleurs, sans comprendre fondamentalement que là où il y a une chose, il y en a probablement plus d'une.

Bien qu'il existe de nombreuses pénalités en termes de performances pour ce type de conception, la plus importante est qu'elle n'est pas évolutive. Du tout. Cent roquettes coûtent cent fois plus qu'une roquette. Et il est extrêmement probable que cela coûte encore plus que cela! Même pour un non-programmeur, cela ne devrait pas avoir de sens. Économie d'échelle. Si vous avez plus de quelque chose, cela devrait coûter moins cher, pas plus cher. Et la façon de le faire est de concevoir correctement les données et de regrouper les choses par des transformations similaires.

Voici mes problèmes avec ce mensonge en particulier.

  1. Le code est un modèle / carte d'un monde imaginaire, car la modélisation du monde imaginaire aide (au moins moi, personnellement) à visualiser et à organiser le code.

  2. Avoir une classe "Rocket" est, pour moi, un choix parfaitement valable pour une classe. Peut-être que les "fusées" pourraient être décomposées en types de fusées comme AGM-114 Hellfire, etc. qui contiendraient la force de la charge utile, la vitesse maximale, le rayon de braquage maximal, le type de ciblage, etc. et une vitesse.

  3. Bien sûr, avoir 100 fusées coûte plus d'une fusée. S'il y a 100 Rockets à l'écran, il doit y avoir 100 calculs différents pour mettre à jour leur position. Le deuxième paragraphe semble donner à penser que s'il y a 100 fusées, cela devrait coûter moins de 100 calculs pour mettre à jour l'état?

Mon problème ici est que l'auteur présente un modèle de programmation «imparfait» mais ne présente aucun moyen de le «corriger». Peut-être que je trébuche sur l'analogie de la classe Rocket, mais j'aimerais vraiment comprendre le raisonnement derrière ce mensonge. Quelle est l'alternative?


9
@gnat: Cette question relève directement de la conception de logiciels, je suis donc enclin à lui donner une certaine latitude.
Robert Harvey

12
Ce billet de blog est assez mal écrit et ne défend pas et ne soutient pas trop bien ses revendications. Je n'y penserais pas beaucoup.
whatsisname

21
Celui qui a écrit cette citation est un idiot avec peu de compréhension des concepts OO ou comment ceux-ci sont mis en œuvre dans le logiciel. Premièrement, nous ne faisons pas la cartographie avec un monde imaginaire, nous faisons la cartographie avec le monde réel. Et si vous avez 100 roquettes, seul l'état des roquettes supplémentaires utilise des ressources supplémentaires, pas le modèle ou le comportement. Il semble avoir des idées différentes à ce sujet et suggère de résoudre un problème qui n'existe pas. Le «regroupement de choses similaires» en tant qu'optimisation peut parfois avoir du sens, mais est totalement indépendant de l'utilisation de classes ou non. Si vous voulez apprendre, évitez ce charlatan.
Martin Maat

3
Étant donné que l'auteur n'a pas pris la peine d'écrire plus de 5 paragraphes au total expliquant les "3 grands mensonges", vous avez probablement passé plus de temps à réfléchir à l'article qu'à lui. S'il ne prend pas la peine de faire un effort, vous ne devriez pas non plus.
Caleb

9
Je pense que ce qu'il veut dire est, avez-vous vraiment besoin de 100 [probablement dynamiquement alloués avec des méthodes virtuelles aussi] "objets fusée", par opposition à une liste de positions, une liste de vitesses, etc. (avoir une liste de toutes les positions et un liste de vitesses signifie que vous pourriez être en mesure d'utiliser des instructions vectorielles pour ajouter la vitesse à la position sur chaque mise à jour de tick plutôt que d'écrire une boucle naïve à travers une liste d'objets)
Random832

Réponses:


63

Tout d'abord, regardons un certain contexte: il s'agit d'un concepteur de jeu écrivant sur un blog dont le sujet est en train de sortir la dernière baisse de performance d'un CPU Cell BE. En d'autres termes: il s'agit de la programmation de jeux sur console, plus spécifiquement, la programmation de jeux sur console pour la PlayStation 3.

Maintenant, les programmeurs de jeux sont un groupe curieux, les programmeurs de jeux sur console encore plus, et le Cell BE est un processeur plutôt étrange. (Il y a une raison pour laquelle Sony a opté pour un design plus conventionnel pour la PlayStation 4!)

Nous devons donc examiner ces déclarations dans ce contexte.

Il y a aussi quelques simplifications dans ce billet de blog. En particulier, ce mensonge n ° 2 est mal présenté.

Je dirais que tout ce qui fait abstraction du monde réel est un modèle dans un certain sens. Et comme le logiciel n'est pas réel, mais virtuel, c'est toujours une abstraction et donc toujours un modèle. Mais! Un modèle n'a pas besoin d'avoir une correspondance 1: 1 nette avec le monde réel. C'est, après tout, ce qui en fait un modèle en premier lieu.

Donc, dans un certain sens, l'auteur a clairement tort: ​​le logiciel est un modèle. Période. Dans un autre sens, il a raison: ce modèle n'a pas du tout à ressembler au monde réel.

Je vais donner un exemple que j'ai déjà donné dans d'autres réponses au fil des ans, le (in) fameux exemple d'introduction au compte bancaire OO 101. Voici à quoi ressemble un compte bancaire dans presque toutes les classes OO:

class Account {
  var balance: Decimal
  def transfer(amount: Decimal, target: Account) = {
    balance -= amount
    target.balance += amount
  }
}

Donc: balancec'est des données , et transferc'est une opération .

Mais! Voici à quoi ressemble un compte bancaire dans presque tous les logiciels bancaires:

class TransactionSlip {
  val transfer(amount: Decimal, from: Account, to: Account)
}

class Account {
  def balance = 
    TransactionLog.filter(t => t.to == this).map(_.amount).sum - 
    TransactionLog.filter(t => t.from == this).map(_.amount).sum
}

Donc, maintenant transferc'est des données et balancec'est une opération (un repli à gauche sur le journal des transactions). (Vous remarquerez également que TransactionSlipc'est immuable, balanceest une fonction pure, le TransactionLogpeut être une infrastructure de données "presque" immuable uniquement en annexe… Je suis sûr que beaucoup d'entre vous ont repéré les bogues de concurrence flagrants dans la première implémentation, qui disparaissent maintenant comme par magie .)

Notez que ces deux sont des modèles. Ces deux éléments sont également valables. Les deux sont corrects. Ces deux modèles la même chose. Et pourtant, ils sont exactement duaux les uns aux autres: tout ce qui est des données dans un modèle est une opération dans l'autre modèle, et tout ce qui est une opération dans un modèle est des données dans l'autre modèle.

Donc, la question n'est pas de savoir si vous modélisez le "monde réel" dans votre code, mais comment vous le modélisez.

Il s'avère que le deuxième modèle est en fait aussi le fonctionnement de la banque dans le monde réel. Comme je l'ai laissé entendre ci-dessus, ce deuxième modèle est principalement immuable et pur, et à l'abri des bogues de concurrence, ce qui est en fait très important si vous considérez qu'il y a peu de temps, il y TransactionSlipavait de vrais bouts de papier envoyés via cheval et calèche.

Cependant, le fait que ce deuxième modèle corresponde réellement à la fois au fonctionnement des services bancaires dans le monde réel et au fonctionnement des logiciels bancaires dans le monde réel, ne le rend pas automatiquement plus «correct». Parce que, en fait, le premier («mauvais») modèle se rapproche assez étroitement de la façon dont les clients bancaires perçoivent leur banque. Pour eux , transferc'est une opération (ils doivent remplir un formulaire), et balancec'est une donnée au bas de leur extrait de compte.

Donc, il peut très bien être vrai que dans le code moteur du jeu de base d'un jeu de tir PS3 haute performance, il n'y aura pas de Rockettype, mais il y aura quand même une modélisation du monde en cours, même si le modèle a l'air bizarre à quelqu'un qui n'est pas un expert dans le domaine de la programmation du moteur physique des jeux sur console.


1
Cela ne signifierait-il pas qu'un bon code modélise le monde réel et qu'en fait ce n'est qu'une mauvaise compréhension du monde réel qui cause un mauvais modèle et donc un mauvais code?
yitzih

14
Je préfère le formuler comme «parfois, le monde réel n'est pas ce que vous pensez qu'il est» ou «ce qui est« le monde réel »dépend du contexte». (Encore une fois, pour un propriétaire de compte bancaire, les données au bas de leur déclaration sont très réelles, tandis que pour un employé de banque , elles sont éphémères.) Je pense que la déclaration dans le blog est principalement due au fait que l'auteur ne comprend pas que "la modélisation le monde réel "ne signifie pas" prendre une photo et faire de tout ce que vous y voyez une classe ".
Jörg W Mittag

Le front-end de votre application de banque en ligne traitera probablement balancecomme des données et des transactions comme plus de données et des transferts comme des opérations, car c'est ce que l'utilisateur voit, même si le back-end peut le traiter différemment.
user253751

@yitzih: chaque modèle est une abstraction et une simplification, vous pouvez donc accuser chaque modèle d'être incorrect, mais ce n'est pas constructif. Chaque modèle doit remplir un objectif et doit être suffisamment bon pour cela, sans gaspiller les ressources pour des choses inutiles. Pour un logiciel d'un gouvernement, un humain peut être quelqu'un qui peut participer aux élections, doit payer des impôts ou peut être marié à un autre humain, pour notre logiciel CRM, un humain est quelqu'un qui est associé aux commandes et qui a une adresse de livraison (et ni montre comment il mange)…
Holger

2
Si l'homme sait quelque chose sur la banque, il trouvera la seconde plus facile, et puisque les techniques bancaires qu'il connaît ont été inventées pour faire fonctionner la banque, il peut créer un logiciel bancaire qui fonctionne. Non pas parce que le deuxième modèle est "plus proche du monde réel", mais parce qu'il décrit une meilleure banque. Le premier modèle pourrait être une représentation tout aussi précise d'une banque dysfonctionnelle du monde réel! Devinez quoi: si vous voulez un bon logiciel bancaire, les programmeurs doivent apprendre à bien faire les opérations bancaires, ne serait-ce qu'à partir des documents requis.
Steve Jessop

19

Je ne suis pas d'accord avec chaque "mensonge" qu'il propose.

TL; DR L'auteur de cet article essayait d'être controversé pour rendre son article plus intéressant, mais les soi-disant «mensonges» sont acceptés par les développeurs de logiciels pour de bonnes raisons.

Mensonge n ° 1 - Big O est important à des fins de mise à l'échelle. Personne ne se soucie si une petite application prend plus de temps, ce qui est la seule constante de temps qui compte, ils se soucient que lorsqu'ils doublent la taille d'entrée, cela ne multiplie pas le temps d'exécution par un facteur de 10.

Mensonge n ° 2 - La modélisation des programmes d'après le monde réel permet à un programmeur qui examine votre code 3 ans plus tard de comprendre facilement ce qu'il fait. Le code doit être maintenable ou vous devrez passer des heures à essayer de comprendre ce que le programme essaie de faire. Une autre réponse suggère que vous pouvez avoir des classes plus génériques comme LaunchPadet MassiveDeviceMover. Ce ne sont pas nécessairement de mauvaises classes, mais vous en auriez toujours besoin Rocket. Comment quelqu'un est-il censé savoir ce que MassiveDeviceMoverfait ou ce qu'il bouge? S'agit-il de montagnes, de vaisseaux spatiaux ou de planètes? Cela signifie essentiellement que l'ajout de classes comme MassiveDeviceMoverrend votre programme moins efficace (mais peut-être bien plus lisible et compréhensible).

De plus, le coût du temps de développement a commencé à dépasser le coût du matériel il y a longtemps. C'est une horrible idée de commencer à essayer de concevoir avec l'optimisation au premier plan de vos pensées. Vous le programmez de manière simple et compréhensible, puis ajustez votre programme après avoir découvert les parties de vos programmes qui prennent beaucoup de temps à s'exécuter. N'oubliez pas: 80% du temps d'exécution est utilisé par 20% du programme.

Mensonge n ° 3 - Le code est extrêmement important. Un code bien écrit (et modulaire) permet une réutilisation (permettant d'économiser d'innombrables heures de travail). Il vous permet également de passer au crible et de reconnaître les mauvaises données afin qu'elles puissent être traitées. Les données sont merveilleuses, mais sans le code, il serait impossible d'analyser et d'obtenir des informations utiles.


5
Je pense que je suis plus sympathique à # 3. En 30 ans de programmation, la grande majorité des bogues, des problèmes de performances et d'autres problèmes que j'ai vus ont été résolus en corrigeant la représentation des données. Si les données sont correctes, le code s'auto-écrit pratiquement.
Lee Daniel Crocker

6
Le vrai problème avec # 3 est qu'il compare les pommes avec les oranges, et non que le code est plus important que les données ou vice versa.
Doc Brown

3
Les données d'entrée sont hors de vos mains, mais la façon de représenter les données dans votre logiciel est entièrement en elles. Vous appelez peut-être cette partie du "codage", mais je pense que ce n'est pas le cas: par exemple, elle est souvent indépendante de la langue et se fait souvent avant le début du codage. Je suis d'accord, cependant, que le code qui nettoie les données d'entrée laides est souvent une bonne chose; mais vous ne pouvez pas le faire avant d'avoir une définition de "propre".
Lee Daniel Crocker

3
En fait, je ne pense pas que le mensonge n ° 3 soit un mensonge. Fred Brooks a déjà écrit il y a des décennies: "Montrez-moi vos organigrammes et cachez vos tableaux, et je continuerai à être mystifié. Montrez-moi vos tableaux, et je n'aurai généralement pas besoin de vos organigrammes; ils seront évidents." (De nos jours, nous parlerions probablement plutôt d '«algorithmes» et de «types de données» ou de «schémas».) Ainsi, l'importance des données est bien connue depuis longtemps.
Jörg W Mittag

1
@djechlin Mon point n'était pas que les données ne sont pas importantes ou que le code est plus important. Simplement, ces données ne sont pas plus importantes que le code. Ils sont tous deux très importants et dépendent fortement les uns des autres.
yitzih

6

Dans un système de commerce électronique, vous ne traitez pas de «fusées» au niveau d'une classe, vous traitez de «produits». Cela dépend donc de ce que vous essayez d'accomplir et du niveau d'abstraction souhaité.

Dans un jeu, on pourrait soutenir que les roquettes ne sont qu'un des nombreux "objets en mouvement". La même physique s'applique à eux qu'à tous les autres objets en mouvement. Donc, à tout le moins, la "fusée" va hériter d'une classe de base "d'objets en mouvement" plus générale.

Quoi qu'il en soit, l'auteur du passage que vous avez cité semble avoir un peu exagéré son cas. Les roquettes peuvent toujours avoir des caractéristiques uniques, comme la «quantité de carburant restante» et la «poussée», et vous n'avez pas besoin d'une centaine de classes pour représenter cela pour cent roquettes, vous n'en avez besoin que d'une. La création d'objets est assez peu coûteuse dans la plupart des langages de programmation décents, donc si vous avez besoin de suivre des choses semblables à des fusées, l'idée que vous ne devriez pas créer des objets Rocket parce qu'ils pourraient être trop chers n'a pas beaucoup de sens.


5

Le problème avec le monde réel est tout ce maudit physique. Nous séparons les choses en objets physiques dans le monde réel parce qu'ils sont plus faciles à déplacer que les atomes individuels, ou un laitier fondu géant de quelque chose qui pourrait potentiellement être une fusée.

De même, le monde réel fournit un certain nombre de fonctionnalités utiles sur lesquelles nous nous appuyons. Il est vraiment facile de faire des exceptions Penguin - "tous les oiseaux volent, sauf ...". Et c'est vraiment facile d'étiqueter les choses comme des fusées, je veux dire si j'appelle ce pingouin une fusée et que je l'allume ... ça ne marche tout simplement pas.

Donc, comment nous séparons les choses dans le monde réel fonctionne conceptuellement sous ces contraintes. Lorsque nous faisons des choses dans le code, nous devons séparer les choses pour bien fonctionner sous ces contraintes, qui sont décidément différentes.

Quelle est l'alternative?

Pensez aux réseaux. Nous ne modélisons pas les ports, les fils et les routeurs en code. Au lieu de cela, nous résumons la communication réseau en connexions et protocoles. Nous le faisons parce que c'est une abstraction utile quelle que soit la mise en œuvre dans le monde réel. Et il met des contraintes utiles (par exemple: vous ne pouvez pas communiquer jusqu'à ce que la connexion soit ouverte) qui ne comptent que dans le code .

Alors oui, parfois modéliser du code après que le monde réel fonctionne, mais c'est une coïncidence . Lorsque les gens parlent de POO, les objets ne sont pas des objets du monde réel. Que les écoles et les tutoriels disent le contraire est une tragédie de plusieurs décennies.


1
+1: Les protocoles sont vraiment une abstraction "du monde réel". Même dans le monde d'aujourd'hui, les agents du protocole sont parmi les membres du personnel les plus importants pour une visite d'État, par exemple. Qui passe le premier sur le tapis rouge lors de la réunion du G8, Obama ou Poutine? S'embrassent-ils ou se serrent-ils la main? Comment saluer un arabe contre un indien? Etc. Nous avons beaucoup de «choses» dans le «monde réel» qui ne sont pas des «choses» dans le «monde physique». Modéliser le monde réel ne signifie pas modéliser le monde physique. Même s'il n'y a pas de Rockettype dans le code de ce type, je suis prêt à parier qu'il existe néanmoins un modèle de…
Jörg W Mittag

… Le monde réel, même s'il ne correspond à rien de «physique» (au sens de «palpable»). Je ne serais pas trop surpris d'y trouver de véritables objets "physiques" (au sens de "choses qu'un physicien pourrait reconnaître"), comme des quaternions, des tenseurs, des champs, etc. qui sont, bien sûr, également " les choses du monde réel "et" les modèles du monde réel ".
Jörg W Mittag

Alan Kay envisageait le Dynabook comme un ordinateur qui serait donné aux enfants à la naissance et qui deviendrait une extension de leur cerveau. Le but du modèle MVC serait alors de faire en sorte que la vue et le contrôleur comblent l'écart entre le cerveau et le modèle pour prendre en charge la métaphore de la manipulation directe, c'est-à-dire l'illusion que l'ordinateur n'est qu'une extension du cerveau, et que l'on peut manipuler directement les objets modèles avec ses pensées. Et c'est ce que nous voulons dire lorsque nous disons que le modèle de domaine modélise le «monde réel». Il devrait mettre en œuvre les abstractions dans notre cerveau.
Jörg W Mittag

Et quand je pense à un moteur physique de jeu de console, alors je ne pense probablement pas aux fusées, et donc il ne devrait pas y avoir de modèle de fusée dans mon code. Mais je pense probablement à d'autres "pensées du monde réel", et il devrait y avoir des modèles de celles-ci dans le code.
Jörg W Mittag

2

L'alternative est de modéliser les choses qui intéressent vos programmes. Même si votre programme traite des roquettes, vous n'aurez peut-être pas besoin d'avoir une entité appelée a Rocket. Par exemple, vous pourriez avoir une LaunchPadentité et une LaunchScheduleentité et une MassiveDeviceMoverentité. Le fait que tout cela aide au lancement de roquettes ne signifie pas que vous manipulez vous-même les roquettes.


0

Mon problème ici est que l'auteur présente un modèle de programmation «imparfait» mais ne présente aucun moyen de le «corriger». Peut-être que je trébuche sur l'analogie de la classe Rocket, mais j'aimerais vraiment comprendre le raisonnement derrière ce mensonge. Quelle est l'alternative?

C'est le vrai problème, mais je vais vous donner mon avis en tant que développeur, peut-être que cela vous aidera.

Tout d'abord, je ne dirais pas que tout cela est un mensonge, comme des idées fausses courantes. Le dire est un battage médiatique.

Celui qu'il a raison, à certains égards. Je ne vais pas y consacrer beaucoup de temps, car cela ne fait pas partie de la question. Mais en substance, il a raison. Je pourrais reformuler ceci comme «ce qui fonctionne dans un laboratoire peut ne pas fonctionner dans la vraie vie». Trop souvent, les développeurs s'en tiennent à une conception qui fonctionne dans un "laboratoire" mais échoue dans les applications du monde réel.

Three Sounds un peu de savon pour moi, mais essentiellement il a encore raison. Mais cela pourrait être réécrit pour "écrire du code autour de vos besoins, n'essayez pas d'adapter les besoins à votre code."

Deux fois encore, ici il a raison. J'ai vu des développeurs passer des semaines ou plus à développer une classe "fusée" alors qu'une classe "véhicule" simple fonctionnerait, ou une classe "mobile" encore plus simple. Si tout ce que votre fusée doit faire est de se déplacer du côté gauche de l'écran vers la droite et d'émettre un son, alors vous pouvez utiliser la même classe que vous avez utilisée pour les voitures, les trains, les bateaux et les mouches. Le 100 devrait coûter moins que l'argument 1 * 100 semble être consacré au temps de développement, et pas tellement aux coûts de calcul. Bien que s'en tenir à moins de classes générales à réutiliser soit «moins cher», alors de nombreuses classes spécifiques ne peuvent pas être réutilisées. Cela pourrait probablement être réécrit car "les classes générales sont meilleures que les classes spécifiques,

Essentiellement, l'article entier pourrait être réécrit, avec moins de mots à la mode et ce ne serait au mieux qu'un paragraphe long. Cela dit, il s'agit d'un article de blog axé sur un domaine étroit de la programmation. J'ai fait de la programmation intégrée, et je suis d'accord, avec l'idée générale derrière ces déclarations, bien qu'il y ait pas mal de "fluff" autour d'eux pour le rendre approprié pour une présentation à GDC.

Une dernière note, l'article a été écrit en 2008 (du mieux que je puisse dire). Les choses changent rapidement. Les déclarations sont vraies aujourd'hui, mais les systèmes embarqués sont beaucoup plus courants aujourd'hui qu'à l'époque, et les modèles de développement changent. Peut-être même en réponse à cet article / discours.


-1

Je trouve intéressant que ces mensonges tournent autour des préoccupations académiques: la plate-forme, l'efficacité de l'utilisation de la mémoire et les données. Mais il ignore complètement l'élément humain.

Le logiciel vise à répondre aux besoins des gens. En règle générale, cela est quantifié en termes commerciaux - il y a des clients qui veulent quelque chose et des bailleurs de fonds qui sont prêts à payer pour y arriver. Si un logiciel est écrit de manière à répondre aux besoins des deux côtés de l'équation, alors c'est un bon logiciel, sinon, c'est un mauvais logiciel.

Si la plateforme n'est pas importante pour le client, alors la plateforme n'est pas importante. Si l'efficacité de la mémoire n'est pas importante pour le client, elle n'est pas importante. Si les données ne sont pas importantes pour le client, les données ne sont pas importantes. Si le code fonctionne, mais ne peut être lu ou maintenu, et que le client souhaite des changements rapides et fiables à un prix décent, alors un code mal écrit est une mauvaise chose. Si le code fonctionne, mais ne peut pas être lu ou maintenu, et que le client ne se soucie pas ou est prêt à payer pour des refacteurs coûteux, un code mal écrit est une bonne chose.

Le gros mensonge est que tout sauf l'élément humain compte. Pourquoi les données sont-elles importantes? Parce qu'il y a un client ou une partie prenante qui en a besoin. Telle est la "grande vérité".


4
Malheureusement, les clients veulent un code rapide et sale, facile à lire et à entretenir, bon marché, sans efforts de test et sans bogue.
Gonen I

@ user889742 Ha! Vrai. Vous avez précisément expliqué le problème d'ingénierie que les architectes tentent de résoudre depuis toujours et ce qui fait de l'industrie un espace si intéressant pour travailler.
Price Jones

Il ignore l'élément humain car il est développeur de jeux et l'ère de la maintenance d'un jeu est relativement courte, bien que plus longue aujourd'hui qu'en 2008. Les correctifs du jour 1 semblent être la norme dans le jeu aujourd'hui. En 2008, les correctifs pour les jeux étaient encore relativement rares.
RubberDuck

-1

À mon humble avis, si le code est "conçu autour d'un modèle du monde", il est plus facile à comprendre, tant pour les concepteurs et les développeurs que pour les responsables. Mais je pense que ce n'est pas seulement moi, et pas seulement un logiciel. Tiré de Wikipédia: La modélisation scientifique est une activité scientifique dont le but est de faciliter la compréhension, la définition, la quantification, la visualisation ou la simulation d'une partie ou d'une caractéristique du monde en la référant à des connaissances existantes et généralement acceptées.

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.