E 'una violazione del principio Open-Closed aggiornare una costante che rappresenta un valore del mondo reale?

9

Ho una classe che calcola il reddito annuale netto dei lavoratori. Ha una costante che rappresenta una percentuale di tasse. Ma un giorno l'aliquota d'imposta è cambiata, quindi ho bisogno di correggere il codice.

L'atto di correggere questa costante indica una violazione del principio Open-Closed , poiché postula che una classe dovrebbe essere chiusa alla modifica?

    
posta Analysis Paradisys 07.12.2017 - 14:22
fonte

5 risposte

13

L'OCP può essere meglio compreso quando si pensa a classi o componenti forniti da un fornitore A in una sorta di libreria black-box, per l'utilizzo da parte degli utenti B, C e D (si noti che questo è solo un modello mentale che sto usando per chiarezza, non importa se in realtà l'unico utente della classe è A stesso).

Se B, C e D possono utilizzare o riutilizzare le classi fornite per diversi casi d'uso, senza la necessità di modificare il codice sorgente della biblioteca, il componente soddisfa l'OCP ( rispetto a una categoria di casi d'uso ). Ci sono diversi modi per raggiungere questo obiettivo, come

  • rendendo la classe ereditabile (in genere in combinazione con il modello di metodo del modello o il modello di strategia)

  • fornendo "punti di iniezione" per l'iniezione di dipendenza

  • fornendo i parametri di configurazione per la classe o il componente (ad esempio, avendo un parametro costruttore "percentuale di tassazione", come nel tuo caso, o utilizzando un altro meccanismo di configurazione)

  • forse altri mezzi, a seconda del linguaggio di programmazione o dell'ecosistema

Gli esempi tipici che trovi nei libri di testo sono spesso di primo o secondo tipo (immagino perché agli occhi degli autori di questo libro, il terzo tipo è troppo banale per essere menzionato).

Come vedi, questo non ha nulla a che fare con la proibizione di modificare il codice sorgente dal fornitore A (come per correggere bug, ottimizzare o aggiungere nuove funzionalità in un modo compatibile all'indietro), che è del tutto estraneo all'OCP. L'OCP riguarda il modo in cui A progetta l'interfaccia e la granularità dei componenti nella lib, quindi scenari di riutilizzo diversi (come il risveglio con aliquote diverse) non inducono automaticamente i requisiti per il cambiamento.

Quindi, nonostante ciò che gli altri ti hanno detto qui, la risposta è chiaramente "sì" , sarebbe una violazione dell'OCP.

EDIT: sembra tra qualcuno ha scritto un post sul blog dettagliato riguardo a questo preciso argomento. Sebbene alcune parti di esso avrebbero potuto essere formulate meglio (come ha sottolineato Derek Elkins), sembra che l'autore condivida in generale il mio punto di vista sul fatto che "rispettare l'OCP" non è una proprietà assoluta, ma qualcosa che può essere valutato solo nel contesto di certe categorie di modifiche dei requisiti.

    
risposta data 08.12.2017 - 07:57
fonte
4

Come altri stanno dicendo, idealmente la classe di reddito dei lavoratori consentirebbe la parametrizzazione della costante, rendendo questa classe indipendente da quel valore.

In definitiva, l'applicazione chiamante potrebbe anche consentire la parametrizzazione in termini di configurazione esterna (ad esempio un file). Una volta configurata la configurazione esterna, è possibile modificare l'aliquota fiscale, anche se si consideri che se il file di configurazione viene letto una sola volta all'avvio, l'applicazione dovrà essere riavviata affinché le percentuali fiscali aggiornate diventino effettive, pertanto è necessario tenere mente. Potremmo fornire una funzione di applicazione per rileggere la configurazione quando richiesto, oppure potremmo fornire un meccanismo più complicato che rileva quando il file di configurazione cambia ...

A lungo termine, potresti scoprire che i problemi fiscali richiedono più di una percentuale - ad esempio, un giorno le leggi fiscali sono più complesse e richiedono diverse percentuali e alcune costanti (ad esempio l'importo inferiore a $ 10 k tassato a X% , mentre il resto è tassato a Y%).

Questo in pratica suggerisce di utilizzare un modello di strategia, in cui la classe principale in questione accetta qui un oggetto strategico per il calcolo della tassa.

Le varie strategie (e% e $ costanti) dovrebbero essere selezionabili dal file di configurazione, e ora, aggiungere una nuova strategia richiede l'aggiunta di qualche nuovo codice, ma non necessariamente gli aggiornamenti al codice esistente.

Ogni strategia potrebbe sapere come analizzare / interpretare i propri argomenti di configurazione esterni, insieme a come calcolare l'imposta effettiva.

Dinamicamente, la tassa può dipendere ulteriormente dalle impostazioni locali, pertanto potresti avere impostazioni locali associate alle entrate o ai dipendenti (o entrambi). Nella configurazione esterna, potremmo associare le impostazioni locali alla strategia fiscale.

Vedi anche iniezione di dipendenza , dove gestiamo esplicitamente queste cose.

    
risposta data 07.12.2017 - 18:44
fonte
1

Se è necessario modificare la classe per modificare il valore dell'imposta, il suo design sta effettivamente violando l'OCP. Il design appropriato, per quello che hai descritto finora, è che la classe calcolatrice assuma come parametro il valore fiscale.

Se la tua classe è istanziata (cioè non è una classe statica), rendendo la proprietà della classe variabile della tassa, il cui valore viene iniettato attraverso la funzione di costruzione, si migliorerà anche la coesione della classe.

In breve, il tuo attuale design fa dipendere la tua classe da un valore costante che non è realmente una costante (definendo una costante come un valore che non cambierebbe mai, non importa quale, come il valore di PI). Viola l'OCP. Modifica il progetto per ricevere il valore dell'imposta come argomento del costruttore.

    
risposta data 08.12.2017 - 18:00
fonte
0

Totalmente d'accordo con @Becuzz, e voglio solo riassumerlo: l'OCP consiste nel trovare astrazioni riutilizzate (quindi utili) che vengono iniettate in una classe. Quindi il comportamento della classe viene modificato non cambiando il suo codice, ma fornendolo con diverse implementazioni. Tutto ciò è reso chiaro nel libro di Robert Martin " Sviluppo, principi, modelli e pratiche software agile ", controlla il corrispondente capitolo "Il principio di Open-closed", "Abstraction is the Key" sottocapitolo. Chiarisce un altro equivoco sul fatto che il comportamento può essere modificato solo con l'ereditarietà. È stato Bertrand Meyer a proporre questo nel 1988 nel suo libro " Costruzione di software orientato agli oggetti ", non Robert Martin.

    
risposta data 07.12.2017 - 17:27
fonte
-2

Il modo in cui lo vedo non è una violazione del principio aperto e chiuso. Tuttavia, il fatto che qualcosa che è destinato a cambiare nel tempo (come la percentuale delle tasse) sia una costante è un difetto di progettazione: non si deve cambiare il valore della costante ma come si gestisce la percentuale delle imposte. Questo dovrebbe essere un qualche tipo di impostazione che potrebbe essere modificata senza ricompilare l'intera cosa.

    
risposta data 07.12.2017 - 17:30
fonte

Leggi altre domande sui tag