2017-06-17 2 views
1

JAVA 8Est-ce une mauvaise conception si l'on ajoute la logique dans getter et setter d'entité classe

J'ai une classe POJO:

class User { 
    private String name; 
    private String password; 

    //... Getters/Setters ... 
} 

que je vais utiliser comme une classe d'entité.

Dans le getter/setter pour password, je souhaite ajouter une logique de décryptage/chiffrement.

public String getPassword() { 
    return EncryptionFactory.decryption(password); 
} 

public void setPassword(String password) { 
    this.password = EncryptionFactory.encryption(password); 
} 

EncryptionFactory est une classe de service qui crypte/décrypter un String.

Ma question est

Sur la base des directives de codage Java général, si j'ajouter une logique de modifier le mot de passe, il ne casse la conception ou son une mauvaise conception? Pendant l'utilisation, j'ai eu de mauvais retours sur la conception de la part de mes professeurs.

+1

Vous utilisez get/setter alors juste obtenir et définir la valeur avec la variable, ne faites rien d'autre. Parce que la conception de celui-ci doit être comme ça, si vous avez besoin de traiter certaines choses, faites-le séparément.Juste image vous publiez votre classe de pojo pour d'autres personnes, ils ne savent pas que vous avez crypter le mot de passe, puis ils le font à nouveau. C'est mauvais –

+3

Jetez un oeil à https://stackoverflow.com/questions/1568091/why-use-getters-and-setters. La première réponse mentionne votre cas d'utilisation - en utilisant une représentation différente de celle exposée par votre interface. –

+0

@CameronSkinner, c'est à dire que nous devrions le faire. droite ? –

Répondre

3

De l'wiki article on mutators:

Souvent, un setter est accompagné d'un getter (également connu sous le nom d'un accesseur), qui renvoie la valeur de la variable de membre privé

Depuis getters sont destiné à donner accès aux valeurs de champs privés, il violerait le principle of least astonishment: une exception pourrait être levée, l'impl de EncrpytionFactory pourrait devenir invalide à un moment donné, etc ... Quand les développeurs s'attendent à simplement accéder à alue. Que vous considériez cette mauvaise conception dépend de la rigueur de vos normes de conception. La meilleure façon de déterminer est de regarder les inconvénients:

  • Impossible d'obtenir le mot de passe crypté
  • forcé d'utiliser String pour mot de passe en texte clair pour stocker le mot de passe (depuis setPassword encrypte automatiquement)
  • Introduit la dépendance de EncrpytionFactory dans le type qui contient get/setPassword

donc, dans votre cas, il est une mauvaise conception.

Bien qu'il existe des cas où il peut être préféré par certains développeurs. Par exemple, si vous aviez un Person#getAge() : int mais utilisé une propriété Date pour gérer l'âge de la personne:

class Person { 
    private Date dateOfBirth; 

    public int getAge() { 
     Date now = ...; //grab date/time right now 
     int age = ...; //calculate age using dateOfBirth and now 

     return age; 
    } 

Certains diront que devrait être découplé le calcul ou getAge doit être nommé calculateAge.

De l'article wiki:

accesseurs permettent à l'inverse pour la synthèse des représentations de données utiles à partir de variables internes tout en gardant leur structure encapsulée et cachée des modules externes. Un accesseur getAmount monétaire peut générer une chaîne à partir d'une variable numérique avec le nombre de décimales défini par un paramètre de devise cachée.


Dans votre cas, il est plus à craindre.

Voulez-vous VRAIMENT déchiffrer le mot de passe, comme dans, y a-t-il une raison? En supposant que vous voulez maintenir la sécurité, il existe des moyens plus sûrs de maintenir un mot de passe.

Chaque fois que vous souhaitez comparer un mot de passe entré à un mot de passe enregistré, il vous suffit de saisir le mot de passe entré et de comparer les résultats au mot de passe enregistré.

Si quelqu'un veut récupérer son mot de passe, il y aurait un risque de sécurité à envoyer son mot de passe à l'utilisateur en texte clair. C'est pourquoi les grandes entreprises exigent que vous réinitialisiez votre mot de passe si vous l'oubliez.


Supposons que vous vouliez conserver le déchiffrement.

Avez-vous vraiment besoin de décrypter à chaque fois quelqu'un appelle getPassword()? Que faire si quelqu'un veut la valeur incrustée?

Vous devez garder le déchiffrement séparé de l'accès. En voyant la façon dont vous avez déjà un EncryptionFactory:

User user = ...; 
String encryptedPassword = user.getPassword(); 
String decryptedPassword = EncryptionFactory.decryption(encryptedPassword); 

Il n'être que quelques fois où votre mot de passe doit déchiffré en fait existe (certains pourraient faire valoir qu'il ne devrait jamais déchiffré en mémoire existent). Le point est, il devrait être complètement facultatif.

Le mot de passe doit être réglé déjà chiffré:

String encryptedPassword = EncryptionFactory.encrpytion(...); 

User user = ...; 
user.setPassword(encryptedPassword); 

Il devrait être accessible sous forme encrpyted. Vous ne devez jamais forcer des risques de sécurité comme celui-ci (déchiffrer un mot de passe), le rendre facultatif.

Enfin, si vous devez exposer une déchiffré getPassword autre, vous devez renommer à decryptPassword():

public String decryptPassword() { 
    return EncrpytionFactory.decryption(getPassword()); 
} 

Bien que cela présente betweeing de couplage unneccesary User (ou quel que soit le type your'e à l'aide) et EncryptionFactory.

Vous devriez vraiment approfondir les aspects de sécurité. Vous should not be maintaining decrypted passwords as String et it's safest if no one but the user knows the password.