[JAVA] Objet de valeur en 3 minutes

Lecteur supposé

--Ingénieur d'application d'entreprise qui a des problèmes dans la conception de classe

Classes communes et leurs problèmes

Classe commune

Créons une classe en utilisant un langage orienté objet tel que Java ou Python. Dans l'exemple ci-dessous, la tâche est représentée sous forme de classe, le nom de la tâche, les points et l'échéance étant conservés sous forme de champs. Il s'agit d'une classe courante qui utilise les types String et int.

Task.java


String taskName;
int point;
Date dueDate;
...

Tenir une méthode getter / setter pour chaque champ que vous détenez est également un modèle d'implémentation courant.

Task.java


    public Point getPoint() {
        return point;
    }
    public void setPoint(Point point) {
        this.point = point;
    }
    ...

Un bref résumé des caractéristiques des classes «communes».

Quel est le problème avec une classe aussi générale?

Problèmes de classe courants

J'ai mentionné deux fonctionnalités plus tôt, mais les classes communes ont des problèmes majeurs qui leur sont liés. Autrement dit, bien qu'il s'agisse d'une classe qui existe pour créer des applications métier, ** "elle a une structure qui autorise les valeurs et les opérations qui enfreignent les règles métier" **. Jetons un coup d'œil au code source réel.

Problèmes à voir dans le code

À titre d'exemple, considérons un champ appelé point dans la classe précédente. Supposons qu'il existe une règle métier selon laquelle "les points doivent être compris entre 0 et 1000". Cependant, puisque les points de la classe Task sont déclarés comme de type int, cela peut également être fait.

task.setPoint(-2000);

Un point qui enfreint la règle métier de -2000 est défini. Rendre cela possible le rend plus sujet aux bogues dans votre logique métier. De plus, ** c'est un bogue logique du point de vue des règles métier, et comme aucune erreur ne se produit en tant que programme, il devient difficile à trouver **, ce qui est un gros problème.

Bien entendu, étant donné que le type int et le type Date ne connaissent pas les règles métier des applications individuelles, il n'est pas possible d'empêcher les actes qui enfreignent les règles métier. De plus, en autorisant la méthode setter, n'importe quelle valeur peut être librement définie de l'extérieur.

Comment résoudre le problème - Essayez d'utiliser des objets de valeur -

Pour expliquer l'objet de valeur à ma manière, c'est ** "une classe qui exprime les règles d'unités et de valeurs utilisées en entreprise" **.

Objet de valeur à regarder dans le code

Si vous regardez le code réel, vous pouvez le voir d'une manière ou d'une autre. Les points sont les deux points suivants.

À l'origine, c'était un setter pour le type int et "tout peut être défini", mais le setter qui ignore les règles métier n'est pas utilisé. Ou plutôt, ne le faites pas. Dans l'objet de valeur, vous devez créer une méthode qui définit la valeur en fonction de la règle métier.

Par exemple, lorsque la méthode add est appelée, canAdd est appelé ensuite et il est vérifié si une valeur contraire à la règle métier (une valeur autre que 0 à 10000) est passée. S'il n'y a pas de problème, une nouvelle instance Point sera créée telle quelle, et s'il y a un problème, une exception sera levée afin qu'une valeur qui enfreint les règles métier ne soit pas définie.

Point.java


public class Point {

    static final int MIN = 0;
    static final int MAX = 10000;

    int value;

    public Point(int value) {
        if (value < MIN) throw new
                IllegalArgumentException("Injustice:" + MIN + "Moins que");
        if (value > MAX) throw new
                IllegalArgumentException("Injustice:" + MAX + "plus de-");
        this.value = value;
    }

    Point add(Point other) {
        if (!canAdd(other)) throw new
                IllegalArgumentException("Illégal: le total est" + MAX + "c'est tout");
        int added = addValue(other);
        return new Point(added);
    }

    boolean canAdd(Point other) {
        int added = addValue(other);
        return added <= MAX;
    }

    private int addValue(Point other) {
        return this.value + other.value;
    }
}

L'objet de valeur créé Point est déclaré et utilisé dans la classe Task d'origine.

Task.java


//Seuls les points sont modifiés en objets de valeur
String taskName;
Point point;    //À l'origine[int point;]
Date dueDate;

En outre, contrairement aux classes "courantes" mentionnées précédemment, vous pouvez facilement obtenir une vue d'ensemble des règles métier simplement en regardant les objets de valeur. De cette façon, l'objet valeur est une méthode de conception très pratique qui non seulement empêche les bogues d'être mélangés, mais aide également à comprendre les spécifications en exprimant les règles métier sous forme de classes **. Veuillez l'utiliser la prochaine fois.

Remarques

Cet article décrit les «objets de valeur» qui apparaissent dans la conception pilotée par domaine, mais n'aborde pas toutes les définitions et caractéristiques strictes des objets de valeur, mais donne uniquement une vue d'ensemble. Notez s'il vous plaît.

Les références

Principes de conception de système utiles sur le terrain ~ Techniques pratiques orientées objet qui rendent les changements faciles et sûrs

Recommended Posts

Objet de valeur en 3 minutes
Points lors du mappage d'un objet de valeur dans MyBatis
Collecte des ordures G1 en 3 minutes
API Java Stream en 5 minutes
Mappage à une classe avec un objet de valeur dans How to My Batis
Inspection continue en 5 minutes avec SonarQube
Valeur initiale lorsqu'il n'y a pas de propriété de l'objet de formulaire dans la requête Spring
Développement Android, comment vérifier null dans la valeur de l'objet JSON
L'objet enregistré en session doit être sérialisable
Inverser la clé de la valeur dans la carte Java
"Hello, World!" Avec Kotlin + CLI en 5 minutes
Fonction de conversion d'objet de liste immuable (immuable) dans Java8
spring-data-jpa @Query renvoie un objet personnalisé
Comprendre en 5 minutes !! Comment utiliser Docker