2009-06-09 5 views
2

Disons que j'ai une classe Customer, qui a une propriété customerType.Appliquer les règles métier de la couche de service aux modifications de propriété d'entité ou masquer la propriété d'entité des clients mais pas du service?

J'ai une autre classe appelée quelque chose comme SpecialContract, qui a un client et d'autres propriétés.

Si customer.customerType == SPECIAL, il existe un contrat spécial qui fait référence à ce client particulier.

Maintenant je me rends compte que c'est un peu hoaky, mais je ne veux pas maintenir une relation du client à SpecialContract pour quelques raisons, l'une étant que la plupart du temps lorsque vous travaillez avec des clients dont nous n'avons pas besoin pour charger SpecialContracts et toutes les autres données associées à SpecialContracts. Cependant, je veux toujours savoir si un client a un contrat spécial, et ceci est réalisé grâce à sa propriété customerType.

Ok, voici la partie difficile. Je ne veux pas que le client puisse définir customerType, car cela ne supprimera pas le contrat spécial qui s'applique au client, ce qui serait nécessaire. Je préfère forcer le client à appeler une méthode de service pour supprimer le contrat spécial, qui définirait également le customerType à NOTSPECIAL en une seule transaction.

Comment puis-je masquer l'accesseur customerType des clients, tout en l'exposant à la classe de ma couche de service qui sera chargée de définir la valeur correcte et de supprimer le contrat spécial? Ma classe de service n'est pas dans le même package que la classe Customer.

+0

semble que vous devez garder un œil sur ces dépendances ... –

Répondre

1

Vous pouvez créer un Interface que Customer implémente et transmettre une instance de ce Interface au client. Ce Interface n'exposerait pas le modificateur contentType au client. Votre service traiterait des objets Customer à part entière et pourrait utiliser le modificateur setContentType tel que défini dans le Class.

+0

Très belle idée, merci! – Boden

0

Pourquoi ne pas faire une analyse sur le système au démarrage à la recherche de tous les Customer s qui ont des références dans SpecialContract s, mémoriser une liste de tous ces Customer s quelque part dans privé, par exemple, la couche de service quelque part?

+0

Je ne suis pas sûr que cela résout le problème. Le problème est de maintenir la cohérence de Customer.customerType et de SpecialContract.customer. Si l'accesseur customerType est privé, je ne peux pas le modifier dans ma couche de service lorsqu'un contrat spécial est détruit. Si c'est public, alors le client peut mettre Customer.customerType à NOTSPECIAL et le conserver sans détruire (immédiatement) le contrat spécial correspondant. Je pense que je dois abandonner cette approche. – Boden

1

Peut-être que la programmation orientée aspect peut être utile ici. Vous pouvez intercepter un appel à un client qui réussit un contrat, demander à la méthode avant d'instancier une sous-classe de contrat spécial dans certaines conditions et transmettre cette méthode à la méthode. Il vous suffit de concevoir la hiérarchie du contrat de manière à respecter strictement le principe de substitution de Liskov. AOP pourrait transformer cela en un gâchis impossible sanglant, mais c'est une façon différente de penser à ce sujet. Vous pouvez ajouter autant de règles que vous le souhaitez et les désactiver ou les déclarer de manière déclarative.

+0

Intéressant, merci. Je pense que je finirais par transformer cela en désordre sanglant impossible si :) – Boden

1

Je ne voudrais pas essayer de cacher le setter de votre client. Au contraire, si le client modifie l'état d'un client et tente de le conserver, vous devez vérifier si SpecialContract/customerType a été modifié de manière inappropriée et peut-être lancer une exception si c'est le cas. Vous pouvez ensuite créer la méthode à laquelle vous avez fait référence précédemment, capable de mettre à jour le type SpecialContract/customerType de manière appropriée. Dans l'ensemble, je pense qu'il serait beaucoup plus sûr d'effectuer cette vérification près de la couche de persistance afin de s'assurer que les données sont correctes avant d'être sauvegardées plutôt que de prendre toutes les données envoyées et de les persister aveuglément.

Questions connexes