2017-01-23 1 views
0

L'encapsulation est-elle correctement conçue dans cette classe? Exemples d'instances d'objets avec des valeurs de hauteur et de largeur négatives peuvent ou ne peuvent pas exister?Si l'encapsulation est correctement conçue dans la classe

import java.awt.Dimension; 
/** * Example class. The x and y values should never * be negative. 
*/ 
public class Example { 
    private Dimension d = new Dimension (0, 0); 
    public Example() {} 
    /** * Set height and width. Both height and width must be nonnegative * or an exception is thrown. */ 
    public synchronized void setValues (int height, int width) throws IllegalArgumentException { 
     if (height < 0 || width < 0) throw new IllegalArgumentException(); 
     d.height = height; 
     d.width = width; 
    } 

    public synchronized Dimension getValues() { // Passing member content by ref 
     return d; 
    } 
} 

Répondre

4

Vous ne pouvez pas appliquer cela. Les gens peuvent toujours modifier les valeurs de hauteur et de largeur via l'objet Dimension que vous renvoyez dans getValues ​​() même si cela viole la loi du principe de déméter.

Example example = new Example(); 
example.setValues(10, 5); 
System.out.println(example.getValues()); // java.awt.Dimension[width=5,height=10] 

Dimension dimension = example.getValues(); 
dimension.height = -1; 
dimension.width = -1; 
System.out.println(example.getValues()); // java.awt.Dimension[width=-1,height=-1] 

De la documentation: https://docs.oracle.com/javase/8/docs/api/java/awt/Dimension.html#width

largeur int publique

La dimension en largeur; les valeurs négatives peuvent être utilisées.

Pour remédier à cette solution pourrait être de renvoyer un clone profond de l'objet Dimension dans getValues ​​() pour empêcher toute modification de l'objet d'origine en utilisant une bibliothèque tels que: https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/SerializationUtils.html#clone(java.io.Serializable)

public synchronized Dimension getValues() { 
    return SerializationUtils.clone(d); 
    // OR return new Dimension(d.width, d.height); 
} 
+4

Vous n » t besoin d'une bibliothèque pour faire un clone profond: 'return new Dimension (d);' fait ce dont vous avez besoin. –

+0

@AndyTurner Je suis d'accord qu'un constructeur de copie suffirait dans le contexte actuel. J'ai suggéré une bibliothèque, car à mesure que les objets deviennent plus complexes, un programmeur novice peut avoir du mal à créer une copie profonde réelle. –

+0

Ce que vous avez essentiellement dit, c'est «Je sais que OP ne veut qu'un clou dans le mur pour accrocher une photo, mais je leur parlerai des excavateurs, au cas où ils auraient besoin de construire une maison». Parlez d'abord aux solutions simples aux débutants, afin qu'ils ne supposent pas qu'ils doivent utiliser des solutions compliquées pour résoudre des problèmes faciles. –