Domanda

Il Principio Aperto/Chiuso afferma che le entità software (classi, moduli, ecc.) dovrebbero essere aperte per l'estensione, ma chiuse per la modifica.Cosa significa questo e perché è un principio importante per una buona progettazione orientata agli oggetti?

È stato utile?

Soluzione

Nello specifico, si tratta di un "Santo Graal" della progettazione in OOP che consiste nel rendere un'entità sufficientemente estensibile (attraverso la sua progettazione individuale o attraverso la sua partecipazione all'architettura) per supportare futuri cambiamenti imprevisti senza riscriverne il codice (e talvolta anche senza ricompilare). **).

Alcuni modi per farlo includono Polimorfismo/Ereditarietà, Composizione, Inversione di controllo (a.k.a.DIP), programmazione orientata agli aspetti, modelli come strategia, visitatore, metodo modello e molti altri principi, modelli e tecniche di OOAD.

** Vedi i 6 “principi del pacchetto”, REP, CCP, CRP, ADP, SDP, SAP

Altri suggerimenti

Significa che dovresti inserire nuovo codice in nuove classi/moduli.Il codice esistente dovrebbe essere modificato solo per la correzione dei bug.Le nuove classi possono riutilizzare il codice esistente tramite ereditarietà.

Il principio aperto/chiuso ha lo scopo di mitigare il rischio quando si introducono nuove funzionalità.Poiché non modifichi il codice esistente, puoi essere certo che non verrà danneggiato.Riduce i costi di manutenzione e aumenta la stabilità del prodotto.

È la risposta al fragile problema della classe base, secondo cui modifiche apparentemente innocue alle classi base possono avere conseguenze indesiderate per gli eredi che dipendevano dal comportamento precedente.Quindi devi stare attento a incapsulare ciò su cui non vuoi fare affidamento in modo che le classi derivate obbediscano ai contratti definiti dalla classe base.E una volta che esistono gli eredi, devi esserlo tu Veramente fai attenzione a ciò che cambi nella classe base.

Più specificamente di DaveK, di solito significa che se desideri aggiungere funzionalità aggiuntive o modificare la funzionalità di una classe, crea una sottoclasse invece di modificare l'originale.In questo modo, chiunque utilizzi la classe genitore non deve preoccuparsi che venga modificata in seguito.Fondamentalmente, è tutta una questione di compatibilità con le versioni precedenti.

Un altro principio molto importante della progettazione orientata agli oggetti è l'accoppiamento libero tramite un'interfaccia del metodo.Se la modifica che desideri apportare non influisce sull'interfaccia esistente, è davvero abbastanza sicuro modificarla.Ad esempio, per rendere un algoritmo più efficiente.Anche i principi orientati agli oggetti devono essere temperati dal buon senso :)

Le entità software dovrebbero essere aperte per l'estensione ma chiuse per la modifica

Ciò significa che qualsiasi classe o modulo dovrebbe essere scritto in modo tale da poter essere utilizzato così com'è, esteso ma mai modificato

Cattivo esempio in Javascript

var juiceTypes = ['Mango','Apple','Lemon'];
function juiceMaker(type){
    if(juiceTypes.indexOf(type)!=-1)
        console.log('Here is your juice, Have a nice day');
    else
        console.log('sorry, Error happned');
}

exports.makeJuice = juiceMaker;

Ora se vuoi aggiungere il tipo Another Juice, devi modificare il modulo stesso. In questo modo stiamo interrompendo OCP .

Buon esempio in Javascript

var juiceTypes = [];
function juiceMaker(type){
    if(juiceTypes.indexOf(type)!=-1)
        console.log('Here is your juice, Have a nice day');
    else
        console.log('sorry, Error happned');
}
function addType(typeName){
    if(juiceTypes.indexOf(typeName)==-1)
        juiceTypes.push(typeName);
}
function removeType(typeName){
  let index = juiceTypes.indexOf(typeName)
    if(index!==-1)
        juiceTypes.splice(index,1);
}

exports.makeJuice = juiceMaker;
exports.addType = addType;
exports.removeType = removeType;

Ora puoi aggiungere nuovi tipi di succo dall'esterno del modulo senza modificare lo stesso modulo.

Il principio implica che dovrebbe essere facile aggiungere nuove funzionalità senza dover modificare quelle esistenti, stabili e testate, risparmiando tempo e denaro.

Spesso il polimorfismo, ad esempio utilizzando le interfacce, è un buon strumento per raggiungere questo obiettivo.

Un'ulteriore regola pratica per conformarsi all'OCP è rendere le classi base astratte rispetto alla funzionalità fornita dalle classi derivate.O come dice Scott Meyers "Rendi astratte le classi non-foglia".

Ciò significa avere metodi non implementati nella classe base e implementare questi metodi solo in classi che a loro volta non hanno sottoclassi.Quindi il client della classe base non può fare affidamento su una particolare implementazione nella classe base poiché non ce n'è.

Voglio solo sottolineare che "Aperto/Chiuso", pur essendo ovviamente utile nella programmazione OO, è un metodo salutare da utilizzare in tutti gli aspetti dello sviluppo.Ad esempio, nella mia esperienza è un ottimo antidolorifico usare il più possibile "Aperto/Chiuso" quando si lavora con il semplice C.

/Roberto

Ciò significa che il software OO dovrebbe essere sviluppato, ma non modificato intrinsecamente.Ciò è positivo perché garantisce prestazioni affidabili e prevedibili dalle classi base.

Recentemente mi è stata data un'ulteriore idea di cosa comporta questo principio:che il principio aperto-chiuso descrive allo stesso tempo un modo di scrivere codice, nonché il risultato finale di scrivere codice in modo resiliente.

Mi piace pensare all'Aperto/Chiuso diviso in due parti strettamente correlate:

  • Codice che è Aprire per cambiare può cambiare il suo comportamento per gestire correttamente i suoi input, oppure richiede modifiche minime per fornire nuovi scenari di utilizzo.
  • Codice che è Chiuso per la modifica non è richiesto molto, se non nessun intervento umano, per gestire nuovi scenari di utilizzo.La necessità semplicemente non esiste.

Pertanto, il codice che presenta un comportamento di apertura/chiusura (o, se preferisci, soddisfa il principio di apertura/chiusura) richiede modifiche minime o nessuna modifica in risposta a scenari di utilizzo oltre a quelli per cui è stato originariamente creato.

Per quanto riguarda l'implementazione?Trovo che l'interpretazione comunemente dichiarata, "Open/chiuse si riferisce al codice polimorfico!" per essere nella migliore delle ipotesi una dichiarazione incompleta.Il polimorfismo nel codice è uno strumento per ottenere questo tipo di comportamento;Ereditarietà, implementazione... in realtà, ogni principio di progettazione orientato agli oggetti è necessario per scrivere codice che sia resiliente nel modo implicito in questo principio.

Nel principio di progettazione, SOLID: la "O" in "SOLID" sta per il principio aperto/chiuso.

Il principio aperto e chiuso è un principio di progettazione secondo cui una classe, i moduli e le funzioni dovrebbero essere aperti all'estensione ma chiusi alla modifica.

Questo principio afferma che la progettazione e la scrittura del codice dovrebbero essere eseguite in modo tale da aggiungere nuove funzionalità con modifiche minime al codice esistente (codice testato).La progettazione dovrebbe essere fatta in modo da consentire l'aggiunta di nuove funzionalità come nuove classi, mantenendo il più possibile invariato il codice esistente.

Vantaggio del principio di progettazione aperto e chiuso:

  1. L'applicazione sarà più solida perché non modificheremo la classe già testata.
  2. Flessibile perché possiamo facilmente soddisfare nuove esigenze.
  3. Facile da testare e meno soggetto a errori.

Il mio post sul blog su questo:

http://javaexplorer03.blogspot.in/2016/12/open-closed-design-principle.html

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top