web-dev-qa-db-fra.com

Comment s'attaquer à l'extensibilité Considérant l'anti-symétrie de données / objet?

En code propre par oncle Bob, il déclare

Code de procédure (code à l'aide des structures de données) facilite l'ajout de nouvelles fonctions sans modifier les structures de données existantes. =OO===== Il facilite l'ajout de nouvelles classes sans modifier les fonctions existantes.

Je lis sur plusieurs dépêches comme dans cet article sur plusieurs envoi et me demandant si cela résout le problème.

Jörg W Mittag dit que cela a été qualifié de problème d'expression de Phil Wadler , mais il déclare que pour résoudre le problème, nous devrions

définissez un type de données par des cas, où l'on peut ajouter de nouveaux cas au type de données et de nouvelles fonctions via le type de données, sans recompiler le code existant et tout en conservant la sécurité de type statique [...]

Je suis plus intéressé par l'extensibilité d'un logiciel, c'est-à-dire s'il est "facile" d'ajouter de nouvelles fonctionnalités progressivement. J'ai une définition intuitive de "facile" dans ce cas, et cela inclut la résistance de bugs et aucun code en double.


Voici oncle Bob Exemples dans le livre

formes polymorphes

public class Square implements Shape {
 private Point topLeft;
 private double side;

 public double area() {
  return side * side;
 }
}

public class Rectangle implements Shape {
 private Point topLeft;
 private double height;
 private double width;

 public double area() {
  return height * width;
 }
}

public class Circle implements Shape {
 private Point center;
 private double radius;
 public final double PI = 3.141592653589793;

 public double area() {
  return PI * radius * radius;
 }
}

Forme de procédure

public class Square {
 public Point topLeft;
 public double side;
}

public class Rectangle {
 public Point topLeft;
 public double height;
 public double width;
}

public class Circle {
 public Point center;
 public double radius;
}

public class Geometry {
 public final double PI = 3.141592653589793;

 public double area(Object shape) throws NoSuchShapeException {
  if (shape instanceof Square) {
   Square s = (Square) shape;
   return s.side * s.side;
  } 

  else if (shape instanceof Rectangle) {
   Rectangle r = (Rectangle) shape;
   return r.height * r.width;
  } 
  else if (shape instanceof Circle) {
   Circle c = (Circle) shape;
   return PI * c.radius * c.radius;
  }
  throw new NoSuchShapeException();
 }
}
7
Jp_

Cela a été appelé le problème d'expression par Phil Wadler, bien qu'il soit beaucoup plus âgé que la discussion dans laquelle il a proposé ce terme. Résoudre c'est l'un des "greils sacrés" de la conception de la langue de programmation.

L'un des problèmes de quelque chose qui est si célèbre est que tout le monde propose ses propres définitions, en en parlant, sans la définir de manière rigoureuse, n'a peu de sens, sauf pour inviter des flammes.

Phil Wadler avait ces quatre contraintes:

  1. Étendez le code avec de nouvelles opérations sur les types de données existants.
  2. Étendre le code avec de nouveaux types de données qui fonctionnent avec les opérations existantes.
  3. Cela devrait être vrai extension, c'est-à-dire aucune modification du code existant.
  4. Il devrait être statique en sécurité.

Les classes ouvertes mutables de style rubis avec des prototypes mutables de type skeyPatching ou de style ECMAScript résolvent les problèmes 1 et 2. Nous pouvons discuter de savoir s'ils vraiment SOLVE POINT 3, cependant: si vous militatez une classe en mémoire, mais le Le code qui effectue cette mutation est dans un fichier séparé ... Est-ce que l'extension ou la modification du code existant?

Donc, disons-ils, ils résolvent 2,5 des problèmes, mais ils ne sont évidemment pas de sécurité statistiques.

MultiMethods de style à fermeture SOLVE 3 Entièrement, mais échoue toujours à 4. Je pense que les multimethods de style de classe Multijava et de tuple peuvent être admissibles, mais je ne suis pas trop familier avec eux.

Les typlasses de Haskell étaient le premier système pour satisfaire les 4 contraintes.

Martin Odersky et al. Ajout de deux autres contraintes:

  1. Il devrait être modulaire, c'est-à-dire que l'extension doit être dans un module séparé (dans le sens PLT du mot) qui est déployé séparément.
  2. Et cela inclut la dactylographie modulaire.

Haskell Typeclasses échoue en réalité à # 6. Scala Valeurs implicites et conversions implicites, cependant DO Résolvez tous les problèmes.

Remarque: Il peut y avoir d'autres caractéristiques de Haskell qui résolvent les 6, mais je ne connais pas trop toutes les extensions et toutes les recherches effectuées depuis des typeclasses.

Pour répondre à votre question actuelle:

Je lis sur plusieurs dépêches comme dans cet article et me demandant si cela résout le problème

Qu'il s'agisse ou non de multiples répercussions du problème dépend de la manière dont vous définissez "Résoudre" et ce que vous considérez "le problème".

9
Jörg W Mittag