Perché il problema di Square-Rectangle viola i principi SOLID?

0

La mia domanda precedente riguardava solo il diagramma di classe e, a causa di alcuni commenti, ho pensato di provare a trovare un esempio con una piccola porzione di codice per il diagramma per vedere se i principi sono stati compresi correttamente?

class Rectangle {
  private int width, height;

  public void setHeight(int h) { height = h; }
  public void setWidth(int w) { width = w; }
  public int area() { return height * width; }
}

class Square extends Rectangle {
  public void setHeight(int h) { height = width = h; }
  public void setWidth(int w) { width = height = w; }
}

// A test function for rectangles
public void areaTest(Rectange rect) {
  rect.setHeight = 20;
  rect.setWidth = 10;
  int area = rect.area();

  assert area == 200;
}

Penso che il primo problema è che Principio di sostituzione di Liskov è ferito perché il quadrato estende il rettangolo quindi non vi è alcun problema nel dire che un quadrato è un rettangolo ma non si può dire che un rettangolo è un quadrato che fa il codice, quindi questo principio è ferito, penso per questo motivo.

Un altro principio ferito credo sia Principio di responsabilità singola perché nel rettangolo di classe, per modificare le proprietà di un rettangolo, ad esempio la sua area (), è necessario modificare l'intera implementazione in per questo motivo, credo che il Principio Aperto / Chiuso sia ferito anche perché se vuoi aggiungere un'estensione, diciamo una funzione di disegno per disegnare gli oggetti (rettangolo / quadrato), non puoi fare questo correttamente.

Penso che altri principi non siano feriti da questo design.

    
posta tenepolis 18.11.2018 - 16:01
fonte

1 risposta

4

Non ci sono problemi con il Principio di Responsabilità Unica. L'SRP non dice che la classe deve fare solo una cosa. Dice che dovrebbe avere solo un motivo per cambiare . Alcuni sosterranno che ciò implica che dovrebbe avere un solo scopo. Quindi per una forma, l'impostazione delle dimensioni e il calcolo di un paio di proprietà relative alla forma sembra perfettamente a posto!

Esiste effettivamente un problema con il principio di sottositurazione di Liskow , poiché l'impostazione dell'altezza cambia anche la larghezza. Questo potrebbe rompere le post-condizioni dei setter (a seconda di come sono espresse queste condizioni). E rompe in ogni caso il vincolo della cronologia, che dice che le proprietà del Rettangolo dovrebbero essere cambiate solo in base ai primitivi dell'interfaccia Rettangolo (cioè nessuna modifica non spiegata).

Modifica : questa volta, non vi è alcun problema con il principio della segregazione dell'interfaccia (grazie agli effetti collaterali quando si modifica la lunghezza o la larghezza). L'inversione delle dipendenze non è rilevante neanche qui.

Sull'Open / CLosed, c'è spazio per la discussione. Le variabili private non dovrebbero essere utilizzate dall'estensione, dal momento che si tratta di un dettaglio di implementazione di Rectangle e Square non dovrebbe saperlo. Quindi non è così aperto per l'estensione: se la classe cambierebbe il modo in cui gestisce l'altezza e la larghezza, l'estensione non funzionerebbe più. Quindi Square dovrebbe utilizzare solo l'interfaccia pubblica. Per migliorare la situazione, potresti considerare di separare l'interfaccia di Rectangle dalla sua implementazione. Ma questo potrebbe essere eccessivo in un caso così semplice.

    
risposta data 18.11.2018 - 18:53
fonte