Informazioni su Bob Martin's Closed for Modification Explanation

1

“Closed for modification.” Extending the behavior of a module does not result in changes to the source or binary code of the module. The binary executable version of the module, whether in a linkable library, a DLL, or a Java .jar, remains untouched.

Hall, Gary McLean (2014-10-10). Adaptive Code via C#: Agile coding with design patterns and SOLID principles (Developer Reference) (p. 208). Pearson Education. Kindle Edition.

In Adaptive Code tramite C #, l'autore cita la spiegazione di Robert C. Martin per Closed for Modification. Come dovremmo capire "La versione eseguibile binaria del modulo, che sia in una libreria collegabile, in una DLL o in Java .jar, rimane invariata."

Possiamo utilizzare modelli di scale per l'albero delle dipendenze in cui le interfacce e le implementazioni si trovano in diversi assembly e possiamo estendere le implementazioni in diversi assembly, ma non siamo sicuri di quanto ragionevole sia. Non penso che copiare il resto del comportamento nella nuova assemblea abbia senso. Qualcuno può per favore visualizzare questa spiegazione con un esempio.

    
posta Tarik 25.03.2015 - 03:07
fonte

4 risposte

1

Can someone please visualize this explanation with an example.

Pensa al modello di strategia, all'iniezione di dipendenza, ecc. Un semplice esempio potrebbe essere un logger che usa un'interfaccia per l'output effettivo .

Una volta definita la "logica aziendale" di controllo del loglevel corretto, questa classe sarebbe vissuta - una volta priva di bug - per sempre intatta. E poiché hai sottratto il output-behavior , potresti inserire diverse implementazioni di output:

  • restituisce un file
  • output in un registro eventi
  • accesso a un database
  • registrazione in formato JSON
  • accesso XML
  • accedere a BSON

L'attuale logger è chiuso per la modifica; non ha bisogno di essere modificato. Un nuovo comportamento potrebbe essere implementato tramite injection injection .

    
risposta data 24.05.2015 - 21:38
fonte
0

Non ho accesso al contesto più ampio della tua citazione, ma credo che la discussione sugli eseguibili sia per lo più retorica. L'idea alla base del principio di open-closed non è che tu vorresti creare una nuova libreria dinamica per ogni estensione del tuo programma, ma che la tua architettura sia strutturata in modo che possa se lo volevi. In altre parole, le nuove funzionalità dovrebbero essere implementate principalmente creando nuovi file, non modificando quelli vecchi, anche le modifiche che non cambiano l'origine, ma richiederebbero la ricompilazione del file oggetto (ad esempio, a causa di una modifica della dimensione di un oggetto dipendente che memorizza).

    
risposta data 25.03.2015 - 13:34
fonte
0

Da un punto di vista di sviluppatori solitari, può sembrare utile estendere i propri moduli o implementare le proprie interfacce in binari distinti.

Tuttavia, tieni presente che non è sempre il caso. Potresti avere team distribuiti con una relazione fornitore / cliente e nessun accesso al codice sorgente reciproco. Potresti essere un consumatore di un framework di terze parti e felice di non dover toccare il codice del framework per adattarlo alle tue esigenze.

Anche la schierabilità è un motivo. Se è possibile identificare una parte di base del comportamento del modulo che sarà relativamente stabile nel tempo e famiglie di comportamenti periferici che si evolveranno molto più spesso, è possibile collocare quelli nei propri eseguibili (o qualsiasi unità dispiegabile in modo indipendente). Ciò consentirà un processo di implementazione molto più gestibile in termini di continuità del servizio, aggiornamento delle dimensioni del pacchetto, potenziale ambito di effetti collaterali, ecc.

    
risposta data 25.03.2015 - 14:45
fonte
-1

Penso che la visualizzazione più semplice sia i metodi di estensione su C #. Puoi aggiungere un comportamento addizionale a una classe, senza dover cambiare quella classe. Il metodo di estensione stesso può essere impostato su una dll diversa. Ruby è un altro esempio in cui questa abilità è stata introdotta dall'inizio.

public static class Extensions
{
    public static bool IsAllCapitals (this string text)
    {
        return text.All(x => Char.IsUpper(x));
    }
}

// Then called
string text = "TEXT";
text.IsAllCapitals();

Sebbene l'idea principale sui principi SOLID, credo, sia l'uso dell'ereditarietà, che può aggiungere un ulteriore comportamento alla classe, senza dover fare il copia / incolla di cui si sta parlando. In questo caso, se si sostituisce qualsiasi metodo di una classe, si dovrebbe comunque chiamare l'implementazione di base. La classe figlio può / dovrebbe essere in una dll separata. Puoi, naturalmente, creare ulteriori metodi pubblici o implementare altre interfacce.

    public interface IA
{
void DoSomething();
}

public class A : IA
{
public virtual void DoSomething()
{
    Console.WriteLine("In A");
}
}

public class B : A
{ 
    public override void DoSomething()
    {
        base.DoSomething();
        Console.WriteLine("In B");
    }
}

Utilizzando DI si può selezionare in fase di esecuzione quale versione si desidera utilizzare, quella originale o quella estesa.

    
risposta data 25.03.2015 - 16:06
fonte

Leggi altre domande sui tag