2009-05-22 2 views
1

J'ai une classe Contact qui contient un objet PortalAccount. Lorsque je souhaite créer un "compte portail" pour un contact, un compte est créé à distance sur une application de portail à l'aide de soap/axis, puis le compte portail du contact est renseigné et le contact est enregistré (la base de données locale contient des informations sur le compte distant, identifiant d'utilisateur et nom d'utilisateur, etc.). J'ai donc une classe de service PortalServiceImpl qui a des méthodes pour créer réellement un utilisateur sur un portail distant, étant donné une instance de Contact. Compte tenu de toutes ces informations, ma question est la suivante: si PortalServiceImpl obtient une instance d'un objet ContactDAO et effectue la sauvegarde, ou si la classe PortalServiceImpl crée simplement l'utilisateur distant, modifiez l'objet Contact transmis, et laisser le client être responsable de l'épargne?Est-ce que plusieurs objets de couche de service doivent partager un DAO?

Méthode 1:

class ServiceFacadeImpl { 
    public void createPortalAccount(Contact contact) { 
    // here the contact is implicitly saved 
    this.portalService.createPortalAccount(contact); 
    } 
} 

Méthode 2:

class ServiceFacadeImpl { 
    public void createPortalAccount(Contact contact) { 
    // here contact is implicitly modified 
    this.portalService.createPortalAccount(contact); 
    this.contactDAO.save(contact); 
    } 
} 

Les deux méthodes se sentent mal pour moi. La méthode 1 est incorrecte car le service PortalService crée un utilisateur distant ET enregistre le contact dans la base de données (bien que via une interface DAO). Méthode 2 se sent mal parce que je dois supposer que le PortalService modifie le contact que je lui passe. J'ai également le sentiment que je ne vois pas d'autres pièges, comme potentiellement ne pas gérer les transactions de manière cohérente.

(BTW, je l'ai déjà utilisé les deux méthodes, et ne veux pas continuer refactoring dans un cercle sans fin. Quelque chose semble tout simplement faux ici.)

+0

Expliquez mieux ce qu'est "portail", pourquoi créez-vous PortalAccount à distance (que se passe-t-il lorsque vous le créez), et pourquoi le sauvegardez-vous dès sa création? – nightcoder

+0

PortalAccount est un objet de domaine local qui contient des informations sur le compte d'un contact sur un portail externe. L'objet PortalAccount n'est pas créé à distance. Toutefois, le PortalService que je décris crée en réalité un compte d'utilisateur sur le portail distant, puis crée et remplit la référence portalAccount d'un contact. Donc, contact.getPortalAccount.getId() retournera l'identifiant de l'utilisateur du contact sur le portail distant (mais il ne frappe pas réellement le portail distant, car cette information est stockée dans la base de données locale). – Boden

Répondre

3

Êtes-vous sûr que c'est une bonne idée que vous avez différents contacter les ID localement et à distance? Cela me semble faux, mais peut-être que je ne connais pas votre domaine.

Dans mon application, tous les nouveaux contacts sont envoyés via le service Web vers le portail distant et y sont enregistrés. Ainsi, lorsque je sauvegarde un nouveau contact localement, il est envoyé à un portail distant et enregistré là. Peut-être que vous avez besoin de la même chose?

Si les pensées ci-dessus sont inacceptables pour vous, alors je le ferais comme ceci:

class ServiceFacadeImpl { 
    public void CreatePortalAccountAndSaveContact(Contact contact) { 
    try 
    { 
     contact.portalAccount = this.portalService.createPortalAccount(contact); 
     this.contactDAO.save(contact); 
    } 
    catch(...) 
    { 
     // do cleanup, for example do you need to delete account from remote 
     // portal if it couldn't be saved locally? 
     // If yes, delete it from portal and set contact.portalAccount = null; 
    } 
    } 
}

Certains diront que CreatePortalAccountAndSaveContact casse responsabilité unique principe, mais imo dans cette situation, il est tout à fait normal parce que, comme je comprendre, vous avez besoin de cette opération pour être atomique. Droite?

Ou vous pouvez ajouter un indicateur booléen à la méthode, indiquant si vous souhaitez enregistrer le contact. Mais si vous avez toujours besoin d'enregistrer le contact avec PortalAccount directement après l'avoir obtenu depuis le portail distant, un indicateur booléen n'est pas nécessaire.

PS. Pourquoi utilisez-vous "this" mot-clé? Le membre privé portalService est-il? Si oui, alors peut-être vous devez reconsidérer votre convention de nommage et nommer des membres privés avec le préfixe "_" par exemple (je pense que c'est le plus populaire), comme _portalService - alors il sera facile de comprendre que _portalService est un membre privé. Désolé pour offtopic.

Bonne chance.

+0

+1 - Je pense que vous avez raison. Le travail du service consiste à coordonner les activités entre entités. Et il se passe probablement beaucoup plus de choses ici en réalité. – jlembke

+0

Merci! Le portail est un service secondaire auquel un "contact" pourrait avoir accès. Je ne stocke pas l'ID localement et à distance ... exactement ... Je stocke des informations sur le compte du portail localement. Ainsi, certains contacts dans le système peuvent avoir un compte sur le portail, et le système "principal" le connaît, mais je n'ai pas à interroger le portail chaque fois qu'un contact est accédé. J'ai simplement utilisé le mot-clé "this" pour rendre mon exemple plus explicite. – Boden

Questions connexes