Rimuovi la dipendenza circolare

1

Ho 2 classi con dipendenze.

public class AuditManager
{
      //set of methods
      public static AuditManager Singleton= new AuditManager();
      public  int AuditEvent(int x){
          Event event=new Event(x);
          event.SaveToDB();
       }
} 

Inoltre ho una classe:

public  class Event 
{
    int x;

    //set of methods

    public Event (int x)
    {
       this.x=x;
    }

    public User getUserOfEvent(int eventId){
        User usr = Respository.Get(eventId);
        Audit.Singleton.AuditEvent(usr.x); //circular dependency between Audit and event
        return usr;
    }

    public int SaveToDB()
   {
      new EventDal(){id=x}.Save(); //EventDal is used a lot in more Entity-type classes
   }

}

Come vedi Audit usa classi come Event (responsabili della rappresentazione del modello) E inoltre, alcune azioni nel modello dovrebbero essere controllate.

Qual è il modo migliore per rimuovere queste dipendenze circolari?

    
posta Badulake 22.09.2017 - 08:15
fonte

2 risposte

9

Il problema generale qui è la classe Event con troppe responsabilità. Dovrebbe essere un contenitore di informazioni stupide, magari con alcuni metodi di persistenza, ma non di più. Tenendo fuori dalla classe qualsiasi logica di dominio, il problema sparirà.

Ad esempio, questo metodo:

    User getUserOfEvent(int eventId){
        User usr = Respository.Get(eventId);
        Audit.Singleton.AuditEvent(usr.x); 
        return usr;
    }

non dovrebbe far parte della classe Event , perché contiene la logica del dominio. In questo esempio, non utilizza nemmeno membri della classe Event , quindi non c'è una ragione chiara per cui debba essere presente. Si può posizionarlo da qualche altra parte, ad esempio in un controller separato o in una classe helper, che risolve la dipendenza ciclica.

Anche se il metodo usasse membri di Event , si può sempre passare l'oggetto evento come parametro al metodo, il che rende possibile rifattorizzare la logica del dominio in un'altra classe. Forse qualche classe EventManager o EventController , o un'altra classe con un nome migliore, a seconda del contesto. Basta fare in modo che Event non dipenda da EventManager , solo viceversa.

Ecco una mia risposta precedente per un problema simile, che mostra tre modi di utilizzare il SRP per rimuovere una dipendenza ciclica in una situazione simile, ma più complessa.

    
risposta data 22.09.2017 - 10:36
fonte
0
public interface IAuditManager {

  public int CreateEvent(int x);

}

public class MyAuditManager : IAuditManager
{
  //...your implementation of IAuditManager, doesn't matter if it's 
  //singleton
}

public class Event  //...or whatever class from your project
{
    public IAuditManager AuditManager { get; set; }
    int x;

    public Event(int x, IAuditManager auditManager) 
    {
        AuditManager = auditManager;
        this.x = x;
    }

    //...whatever you need to do here...
    //no circular dependencies anymore, because you're using
    //dependency injection here
}
    
risposta data 25.09.2017 - 14:01
fonte