Question

Compte tenu de la définition de classe ci-dessous. Comment peut-on aller sur décider si les méthodes stub doivent être statiques ou non statique?

class Point {
    private final int x;
    private final int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    // Should the methods add(), subtract() and inverseOf() be non-static ...

    public Point add(Point point) {

    }

    public Point subtract(Point point) {

    }

    public Point inverseOf() {

    }


    // Or static?

    public static Point add(Point point1, Point point2) {

    }

    public static Point subtract(Point point1, Point point2) {

    }

    public static Point inverseOf(Point point) {

    }
}
Était-ce utile?

La solution

Je pencherais pour les méthodes d'instance. Vous avez alors la capacité de faire les méthodes d'une partie inteface et les remplacer. Vous obtiendrez l'avantage quand vous avez à traiter avec des points 2d ou 3d des points et avoir un code client qui ne se soucie pas vraiment et le besoin d'effectuer des opérations sur les points de mise en œuvre de l'interface.

Autres conseils

Je pense que cela dépend de ce que vous essayez d'accomplir. Si vous fournissez une méthode qui ajoute deux points ensemble alors vous voulez une méthode statique. Mais si vous voulez une méthode qui ajoute un point à un point donné par exemple, vous voulez une méthode non statique.

Si vous utilisez une méthode statique alors vous pourriez envisager de mettre les méthodes statiques dans une classe utilitaire séparé (PointCalculator) qui ne contient que des méthodes statiques. Ceci est similaire à la classe de mathématiques.

Je vais pour les méthodes non statiques qui sont plus orienté objet (oui, en utilisant la méthode trop statique casse l'avantage des objets comme le polymorphisme, l'héritage ...), même si votre Point est immuable. Et en fait, ce serait conforme à la façon dont les classes comme BigDecimal ou BigInteger sont conçus. En plus de cela, méthodes statiques rendent plus difficiles les classes de tester donc je préfère éviter de les utiliser si possible, surtout quand il est logique.

sémantiquement, l'approche statique semble faire un peu plus de sens. Tous deux du travail bien sûr, mais l'approche non-statique donne la priorité à un point sur une autre, et implique en outre que Point1 (la méthode qui ajoute est appelé) peut être modifiée à la suite de l'appel.

En tant que développeur en utilisant vos classes, si je vu ce qui suit:

Point p1 = new Point(1,2);
Point p2 = new Point(2,3);

p1.Add(p2);

ou ..

Point p1 = new Point(1,2);
Point p2 = new Point(2,3);

Point.Add(p1, p2);

mon penchant naturel serait de supposer que la méthode add () dans la version non-statique modifie Point1 pour ajouter le résultat du point 2. Avec l'approche statique, il est plus clair (mais pas garanti!) Que la méthode est pures et les points Represenative ne sont pas modifiés.

A l'aide d'une méthode statique lorsque le corps de la méthode ne dépend pas de l'une quelconque cas particulier.

À titre d'exemple, regardez votre méthode de add(Point, Point). Vous ajoutez ensemble les deux Points qui sont passés à la fonction comme arguments, et en retournant une autre Point. Est-ce vraiment besoin d'une référence this interne à certains Point?

Par contre, vous avez une méthode add(Point). On peut supposer que cela ajoute l'argument de fonction à l'instance -. Dans ce cas, vous devez faire cette méthode une instance si vous avez les deux Points

Modifier : Je pense que j'ai mal compris, à l'origine. En regardant en arrière, vous avez les signatures correctes pour les implémentations statiques et non statiques. À ce stade, je dirais qu'il est une question de style, comme vous le savez les deux fonctionneront correctement. Comment voulez-vous que votre classe de points à utiliser? Pensez si elle rend le code plus intuitif de dire Point a = Point.add(b, c) ou Point a = b.add(c). Personnellement, j'aime le premier, car il me dit que ni des opérandes va être modifié.

Si vous allez utiliser Java et créer des objets, puis stylistiquement, je pense que vous devriez essayer d'utiliser au maximum des objets et l'encapsulation de données. Pour moi, cela signifie laisser les données où il est (dans la classe Point) et ne pas passer à une méthode distincte pour y faire face. Faites vos objets travailler pour vous; pas seulement accesseurs. En fait, réfléchir à la façon dont vous pouvez éviter d'avoir un getter du tout.

Il est tout à fait courant d'avoir des méthodes comme add () et soustraire () sur une classe immuable que le retour de nouvelles instances de la classe immuable. Ceci est un bon style pour la programmation FP comme parfaitement raisonnable pour une classe comme celui-ci. (Voir BigInteger ou BigDecimal pour de bons exemples Vous ne trouvez pas la date ou le calendrier pour les mauvais cassés exemples effrayants:..)

Garder les méthodes de la classe vous permet de définir le cas échéant des interfaces que ces classes pourraient mettre en œuvre, utilisez le décorateur ou motif adaptateur, écrire certains types de tests, etc.

J'ai tendance à l'encontre de la norme à ce sujet, mais de toute façon me semble raisonnable.

  • Les méthodes doivent évidemment faire partie de la méthode du point, car ils traitent spécifiquement des points
  • Pour les méthodes qui utilisent deux points, il n'y a rien à leur sujet qui impliquent qu'ils ont besoin de plus d'informations sur l'un des points que l'autre ... Il n'y a donc pas pousser à quelle instance la méthode serait un membre non-statique .

Pour un langage comme Java, je partirais avec des méthodes statiques, notamment en raison du second point ci-dessus. Pour une langue qui a une surcharge de l'opérateur (comme Ruby), je partirais avec une méthode d'instance pour tirer profit de cela.

Il est naturellement que ces fonctions doit être non statique. Mais si vous doutez s'il vous plaît faites référence à GRASP, ils décrivent des choses comme ça.

Selon GRASP Informations Expert ces fonctions ne doit pas être statique.

En dépit du fait qu'il n'y a pas d'information directe sur la méthode statique, il est

  

Expert information nous conduira à   placer une responsabilité dans les classes avec   les informations les plus nécessaires pour   le remplir.

Si vous vous faites des méthodes vous statiques déplacerez votre logique plus à partir des données réelles et devra transmettre des données à la méthode.

La suppression statique va mettre une logique plus proche des données qu'il utilise.

Ce qui les rend statique rend également plus difficile à l'unité les tester! Le seul cadre moqueur, je suis conscient de .NET qui pourrait gérer cela est Typemock.

Si l'intention est de rendre cette classe immuable, que vous retournerez nouveaux objets Point dans un accesseur, appeler ainsi ce qui les rend statique ne fait pas beaucoup de sens ici.

Ces méthodes doivent être statiques, car la classe elle-même se prête à être créé par le constructeur et attribué une fois les valeurs en raison de x et y étant finale. Cela signifie que vous pouvez créer des points, mais pas manipuler leurs données à l'avenir. Ajout / Soustraire / etc méthodes sont des méthodes d'utilité qui ne devrait pas nécessiter une instance de point à utiliser.

Dans votre cas, il doit être non statique sauf si vous modifiez la signature à public static Point add(Point point1, Point point2).

EDIT : Je suis descendu voté. C'est très bien. Je ne cherche pas à donner suggestion trivial comme mettre statique dans la méthode avant. Dans ce cas, une méthode d'instance est mieux, mais il n'y a vraiment pas roussir réponse. Cela dépend de votre préférence.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top