2015-06-03 24 views
8

INTRODUZIONEQuali principi SOLIDI vengono violati?


Io lavoro sulla mia tesi di laurea sui problemi di successione e di elaborare alcune indicatori che dimostrano che un problema di eredità esiste.

Come il seguente esempio:

ESEMPIO


public static String getAnimalNoise(Animal animal) { 
    if (animal instanceof Dog) 
    return "Woof"; 
    if (animal instanceof Cat) 
    return "Miau"; 
    return ""; 
} 

Il metodo restituisce la stringa "Woof" se il dato caso animale è un Dog e "Miau" se è un Cat. La stringa vuota perché alcuni animali non emettono alcun rumore.

Quindi la soluzione corretta dovrebbe essere il polimorfismo di utilizzo con un metodo getNoise nella classe Animale.

Ho analizzato diversi indicatori di problemi di ereditarietà e voglio dire se alcuni di essi violano uno SOLID Principle.

ho pensato che l'esempio precedente viola il:

  1. principio responsabilità singola (SRP)
  2. Apri/principio chiuso (OCP)
  3. Liskov principio di sostituzione (LSP)
  4. Principio di inversione delle dipendenze (DIP)

Ma non sono proprio sicuro se sia vero per tutti.

ho pensato:

VIOLAZIONI PRINCIPIO


SRP violazione

Perché istruzioni condizionali a tutti viola la SRP, perché, come il caso istruzione switch o più di una dichiarazione if-else sono considerate più di una risposta bilità.

Esistono due casi, quindi esistono più motivi per modificare il metodo.

violazione OCP

Perché se un nuovo animale viene aggiunto un nuovo caso deve essere aggiunto al metodo modo il metodo non è vicino per le modifiche.

LSP VIOLATION

Ogni ramo esegue diverse azioni dipendenti dal tipo animale sub. Quale credo viola lo LSP?! Conosco l'esempio del rettangolo e del quadrato e del getArea ma questi esempi di sono adatti anche alla violazione.

DIP VIOLAZIONE

Le istruzioni condizionali prendono dipendenza che significa che le dichiarazioni dipendono dettagli e non su astrazioni che viola la DIP.

DOMANDA:


Quindi la domanda è, per l'esempio dato, sono i principi indicati davvero violato ed è il ragionamento è corretto?

+0

Questo potrebbe essere più on-topic su Programmers.SE. – MSalters

risposta

8

SRP Perché istruzioni condizionali a tutti viola la SRP, perché come l'istruzione case switch o più di uno se-else sono considerare più di una responsabilità. Esistono due casi, quindi ci sono più motivi per cambiare il metodo.

Sono fortemente in disaccordo. L'SRP deve essere interpretato con un pizzico di sale. Leggi Uncle Bob's article on it here - ha coniato questo principio.

citerò i pezzi importanti:

ciò che definisce un motivo per cambiare?

Questo principio riguarda le persone.

Quando si scrive un modulo software, si desidera assicurarsi che quando vengono richieste modifiche, tali modifiche possano provenire solo da una singola persona, o meglio, da un singolo gruppo di persone strettamente accoppiate che rappresenta una singola funzione aziendale strettamente definita. Si desidera isolare i moduli dalle complessità dell'organizzazione nel suo complesso e progettare i propri sistemi in modo tale che ciascun modulo sia responsabile (risponde) delle esigenze di una sola funzione aziendale.

[...] mentre pensi a questo principio, ricorda che le ragioni del cambiamento sono le persone. Sono le persone che richiedono modifiche. E non vuoi confondere quelle persone o te stesso, mescolando insieme il codice a cui molte persone diverse si interessano per ragioni diverse.


OCP Perché se viene aggiunto un nuovo caso deve essere aggiunto al metodo un nuovo animale in modo che il metodo non è vicino per le modifiche.

Corretto. Il metodo presuppone un insieme specifico di implementazioni e non sarebbe in grado di gestirne di nuove senza essere modificato.


LSP Ogni ramo esegue diverse azioni dipendenti dal tipo animale sub. Quale penso violi l'LSP ?!

Violare l'LSP, ma per un motivo diverso. Se dovessi passare in una giraffa, otterrei un risultato inaspettato, una corda vuota. Il che significa che il metodo non è corretto per qualsiasi sottotipo di Animal.


DIP Le istruzioni condizionali prendono dipendenza che significa che le dichiarazioni dipendono dettagli e non su astrazioni che viola il DIP.

Tecnicamente vero, ma questo è solo un effetto collaterale di violare gli altri due principi sopra. Non è davvero il nocciolo del problema.


Ricordare che i principi non sono regole, quindi non essere troppo rigidi/letterali nell'interpretarli. Pragmatismo e comprensione perché il principio è fondamentale.

+0

Aggiungerei il DIP: il metodo dovrebbe dipendere da un 'MakesNoiseInterface' invece che da classi concrete. – deceze

+0

@deceze Non c'è bisogno di un'interfaccia, esiste già un'astrazione: 'Animale'. Il problema è il controllo di tipo contro animali specifici, e lo risolverei personalmente spostando il metodo 'getNoise' in' Animal', risolvendo tutte e 3 le violazioni. – dcastro

+1

Grazie mille per la risposta veloce! Per SRP penso che tu abbia torto a vedere il libro di Robert C. Martin Codice Clean site 38> Ci sono diversi problemi con questa funzione. Innanzitutto, è grande e quando vengono aggiunti nuovi tipi di dipendenti , crescerà. In secondo luogo, molto chiaramente fa più di una cosa. In terzo luogo, viola il Principio di Responsabilità Unica7 (SRP) perché esiste più di una ragione per la quale lo cambia. Qui il codice di riferimento pulito: https://cleansourcecode.files.wordpress.com/2013/10/clean-code.pdf – Zelldon

1

Non sono d'accordo sul fatto che il codice di esempio viola l'LSP. LSP è definito come segue:

Sia Φ (x) una struttura dimostrabile sugli oggetti x di tipo T. Quindi Φ (y) dovrebbe essere vero per oggetti y di tipo S dove S è un sottotipo di T.

date le due derivazione da animali, vale a dire Dog e Cat e il metodo di getAnimalNoise non si stanno facendo decisioni su alcune proprietà proveable dell'oggetto concreto. Il tuo metodo sta decidendo quale rumore dovrebbe essere restituito e non gli oggetti da solo.

Quindi immaginiamo di poter impostare il numero di zampe per un animale.

Animal a = new Animal() 
a.setLegFront(2); 
a.setLegRear(2); 

E se il vostro Dog sovrascrive questo come questo:

class Dog extends Animal 
{ 
    public void setFrontLegs(int legs) 
    { 
    this.frontLegs = legs; 
    this.rearLegs = legs + 2; 
    } 
    public void setRearLegs(int legs) 
    { 
    // do nothing here for demonstration purposes 
    } 
} 

Se ora avete una fabbrica che restituisce un Animal

Animal createAnimal() 
{ 
    return new Dog(); 
} 
Animal a = createAnimal(); 
a.setFrontLegs(2); 
a.setRearLegs(2); 

E chiamare i metodi setFront/setRearLegs vi aspettate il risultato essere 2 e 2 ma in realtà il risultato è completamente diverso, vale a dire 2 e 4. Quindi questo esempio è strettamente legato al commo n Esempio di LSP con quadrati e rettangoli. Ma per me è un esempio più accurato di violazione delle proprietà dimostrabili che nel tuo esempio.

Aggiornamento per gli altri principi

Sono d'accordo con te che gli altri principi sono violati ma per SRP sono d'accordo con @dcastro.

+0

Grazie. Cosa sono gli altri principi? – Zelldon