2016-06-14 15 views
8

The open/closed principle afferma che una classe deve essere aperta per estensione ma chiusa per la modifica.L'override viola il principio Aperto/Chiuso?

Ho pensato che la parte di modifica si riferisse strettamente alla modifica del codice sorgente della classe base. Ma ho avuto una discussione con qualcuno che diceva che questo comporta anche l'override dei metodi dalla classe base.

Questa interpretazione è corretta?

+2

L'override del metodo nel polimorfismo del sottotipo sarebbe probabilmente più tipicamente associato alle violazioni di sostituzione di Liskov (come nel caso di Circle/Ellipse) di qualsiasi altra cosa. – TheInnerLight

risposta

2

Un override è molto simile a un callback che chiunque può registrare. È tipo:

if (IsOverridden) CallCallback(); 
else DefaultImplementation(); //possibly empty 

In questo senso non c'è alcuna modifica. Stai solo riconfigurando l'oggetto per chiamare la richiamata invece di fare il comportamento predefinito.

È proprio come l'evento click di un pulsante. Non considereresti la possibilità di iscrivere a un evento una modifica. È un'estensione.

1

"Ho pensato che la parte di modifica si riferisse strettamente alla modifica del codice sorgente della classe base."

Hai pensato bene.

C'è una pletora di modi per rendere una classe estensibile e consentire ad essa di ereditare da essa è una di queste. La parola chiave extend viene anche utilizzata in alcune lingue per abilitare l'ereditarietà, il che rende evidente che non stiamo modificando, stiamo estendendo ...

Se l'ereditarietà è la soluzione giusta all'estensibilità o meno è un'altra preoccupazione, ma di solito non è però La composizione dovrebbe essere il modo preferito per rendere le classi estendibili (ad es. Strategia, Osservatore, Decoratore, Tubi e Filtri, ecc ...)

3

I metodi virtuali consentono di sostituire il comportamento di una classe base in una classe derivata, senza dover modificare il classe base e questo significa che aderisci al principio Aperto/Chiuso poiché puoi estendere il sistema senza dover modificare il codice esistente.

Le classi base (che non sono puramente astratte), tuttavia, tendono a violare lo Dependency Inversion Principle, poiché la classe derivata prende una dipendenza dalla classe base, che è un componente concreto invece di essere un'astrazione. Ricorda, il DIP states che:

I moduli di alto livello devono [...] dipendere dalle astrazioni.

Oltre a questo, classi base tendono a violare la Interface Segregation Principle pure nel caso in cui definiscono più metodi comuni (o protetti) che non sono tutti utilizzati dal tipo derivato. Si tratta di una violazione della ISP perché:

nessun cliente dovrebbe essere costretto a dipendere da metodi non utilizza

+0

Non sarei d'accordo sul fatto che avere metodi concreti su una classe base violano l'ISP, dal momento che il client non è costretto a dipendere da essi - non hanno bisogno di implementare metodi che non useranno (come sono già lì), per esempio confrontato con l'implementazione di un'interfaccia e quindi lanciando un 'MethodNotSupportEdexception', o simile. Direi però che il numero di metodi non utilizzati è correlato alla coesione tra sub e super-classe: se molti di essi non sono rilevanti, è probabilmente un odore che hai esteso la classe sbagliata, o un'altra classe deve essere estratto per i punti in comune. – anotherdave

+0

@anotherdave Avere metodi concreti su una classe base non è una violazione dell'ISP, ma avere metodi concreti su una classe base che non sono effettivamente utilizzati da un derivato è una violazione ISP. Se il client li usa o meno è irrilevante, dal momento che l'ISP afferma che "nessun cliente dovrebbe essere costretto a dipendere da metodi che non usa". Lo stesso vale per le interfacce ampie, in cui il client utilizza solo 1 su 10 metodi. Dipende ancora dagli altri 9 metodi, che sono "già lì". – Steven

+0

@anotherdave Ma sì, c'è una correlazione tra il numero di metodi non utilizzati nella classe base e quanto coesiva questa classe. La bassa coesione è spesso un'indicazione di una violazione della Violazione della singola responsabilità. Vedrai spesso abusare delle classi base per implementare preoccupazioni trasversali. Avere più problemi trasversali in una classe base è una violazione SRP. – Steven

0

Form "Codice Adaptive tramite C#" libro, metodi virtuali è uno strumento per raggiungere OCP.

Problemi correlati