Estrarre un modulo o utilizzare direttamente il modulo Singleton?

2

Sto lavorando su un modulo che dipende da altri moduli per alcune funzionalità. Ora il modulo dipendente fornisce molte funzionalità e ho bisogno solo di alcune di esse, quindi ho avuto l'idea di creare un'astrazione dello stesso nel mio modulo che è di nuovo solo un singleton.

La mia domanda è quando astrarre e quando utilizzare direttamente la classe dei moduli Singleton? Esistono linee guida per lo stesso? O dipende dal progetto da proiettare?

    
posta Ravi Gupta 01.02.2013 - 14:50
fonte

4 risposte

3

My question is when to abstract out and when to use the modules singleton class directly?

Mai (sì, mai) usare un singleton.

Non c'è mai uno scenario in informatica dove avere più di una cosa è un errore. Anche i sistemi operativi o l'hardware non sono buoni candidati per i singleton a causa delle macchine virtuali.

I moderni bisogni di testabilità (concorrente) e simultaneità e singoletti forniscono più di un problema. Non è molto più semplice passare semplicemente in un'istanza di simulazione; fallo bene.

    
risposta data 09.04.2013 - 15:04
fonte
0

C'è una regola d'oro nella programmazione e nel refactoring: l'accoppiamento faible et un haut degre de cohesion. (Mi spiace che l'espressione sia in francese) significa che le classi non dovrebbero dipendere pesantemente dalle altre e ogni classe dovrebbe essere molto specifica e ha un solo lavoro. Nel tuo caso se il modulo B dipende parzialmente dal modulo A, puoi refactoring il modulo A e usare delegati (puntatori). L'astrazione è una soluzione solo se 'is instance of' è semanticamente corretta. Ad esempio, in java non è consentita l'ereditarietà multipla. Quindi cosa succede se un modulo dipende parzialmente da due diversi moduli? Ecco perché considerare l'utilizzo dei delegati piuttosto che l'astrazione.

    
risposta data 08.02.2013 - 12:42
fonte
0

Dovresti usare dependency injection e, possibilmente, aggiungere un wrapper di facciata attorno al tuo modulo indipendente.

Fai in modo che il costruttore del tuo modulo dipendente prenda come input un'interfaccia che acceda al tuo modulo dipendente:

public MyDependentModule(IPartsOfIndependentModuleIUse partOfIndependent) {
    _partOfIndependent = partOfIndependent;
}

Avvolgi il tuo modulo indipendente:

public class PartsOfIndependentModuleIUse : IPartsOfIndependentModuleIUse {
    Independent _independent = new Independent();

    public MethodOneThatIUse() {
        _independent.MethodOne();
    }
}

Il pezzo di iniezione delle dipendenze ti consentirà di prendere in giro l'oggetto per testarlo facilmente.

    
risposta data 09.04.2013 - 15:32
fonte
0

Se la tua classe dipendente richiede solo una parte delle funzionalità della classe dipesa (nel tuo caso un singleton), allora ha senso astrarre quella funzionalità in un'interfaccia. Ciò significa che la classe dipendente non è influenzata dalle modifiche al singleton a cui non interessa.

Quindi si utilizza l'iniezione di dipendenza facendo in modo che la classe dipendente faccia riferimento a questa interfaccia nel suo costruttore. Poiché la classe singleton implementa questa interfaccia, può essere passata alla classe dipendente al momento della compilazione. Esempio in C ++ di seguito:

class TheInterface
{
  public:
  virtual void dependentOp1() = 0;
  virtual void dependentOp2() = 0;
};

class TheDependedUpon : TheInterface
{
  virtual void dependentOp1()
  {
    std::cout << "dependentOp1 called!" std::endl;
  }

  virtual void dependentOp2()
  {
    std::cout << "dependentOp2 called!" std::endl;
  }
};

class TheDependent
{
  //Constructor requires an object implementing TheInterface (dependency injection)
  TheDependent(TheInterface& anInterfaceReference)
  {
    //Here we can make calls to the interface we are interested in
    //without knowing how its implemented.
    anInterfaceReference.dependentOp1();
    anInterfaceReference.dependentOp2();
  };

void main()
{
  TheDependedUpon dependedUpon = TheDependedUpon();
  //Here we inject the dependedUpon as a dependency at build time
  TheDependent dependent = TheDependent(dependedUpon); 
}
    
risposta data 13.11.2015 - 11:57
fonte

Leggi altre domande sui tag