È buona prassi dichiarare e impostare proprietà in classi astratte?

4

Sto usando PHP e progettando alcune classi astratte.

Posso dichiarare le proprietà con valori costanti all'interno della mia classe astratta e accedervi / sovrascriverli da qualsiasi classe che estende questo senza re-dichiararli all'interno di una delle classi di estensione.

Un vantaggio a questo è una digitazione meno ripetitiva, ma il lato negativo che l'overtime della struttura / layout originale di queste proprietà astratte viene dimenticato e potrebbe essere lasciato ai valori statici predefiniti o addirittura dimenticato (non utilizzato) completamente.

In che modo viene gestito in ambienti professionali? Presumo che questo sia stato pensato prima e sia favorito o no?

Sto cercando di aderire ai buoni principi OOP / regole come SOLID, DRY e KISS ma non ho visto questo specifico argomento discusso in questi. (forse mi è mancato durante le ricerche?)

    
posta cecilli0n 22.04.2014 - 17:02
fonte

4 risposte

2

Questa potrebbe essere una preferenza personale, ma evito di avere classi base per il gusto di condividere proprietà. In particolare nelle classi di dati. Non mi interessa la ripetizione, e evito di bloccare le mie classi in una gerarchia di "dati" fissa.

Ci sono abbastanza problemi con l'ereditarietà, soprattutto col passare del tempo con la crescita della base di codice, che sono riluttante a condividere metodi attraverso una gerarchia di classi e ancora più riluttante a condividere le proprietà attraverso una gerarchia di classi.

...

Hm. Ho appena notato che hai menzionato le proprietà "statiche". Piuttosto che proprietà statiche (cioè globali) in una classe base, è meglio avere una singola istanza separata di qualcosa distribuito da una fabbrica. Assicurati di prevedere la concorrenza per evitare condizioni di gara.

    
risposta data 22.04.2014 - 17:16
fonte
0

Per rispondere alla tua domanda, sì. Se la classe astratta è il luogo logico per la proprietà, allora mettila lì. Usa gli strumenti che ti danno le classi e OOP.

"overtime the original structure/layout of these abstract properties is forgotten and could be left at there default static values or even forgotten(not used) completely."

Questo implica che gli sviluppatori che utilizzano / creano classi astratte o classi secondarie devono fare qualcosa con queste proprietà. Se ciò è vero, prova a creare un design di classe che costringa uno sviluppatore a occuparsi di questo. È meglio quindi fidarsi di tutti per farlo sempre correttamente.

Hai menzionato la modifica dei valori statici. Le proprietà statiche sono condivise tra tutte le istanze di classe, quindi cambiando il loro valore in un oggetto lo si cambia per tutti. Più oggetti che cambiano lo stato globale è qualcosa che si vuole evitare, perché è difficile mantenere tutte le modifiche nell'ordine corretto.

    
risposta data 22.04.2014 - 23:39
fonte
0

Se mantieni la tua ereditarietà superficiale (l'opposto di lasagna ) allora non c'è nulla di filosoficamente sbagliato nel mettere le proprietà in una classe astratta. Il linguaggio, dopo tutto, lo consente. Mantenere la tua ereditarietà superficiale garantirà che tali proprietà non vengano dimenticate.

L'unica cosa su cui potresti voler prendere seriamente in considerazione è rendere tali proprietà protette. Le classi ereditarie possono sempre allentare la visibilità, ma altrimenti se a un certo punto hai bisogno di trasformare una proprietà pubblica in una protetta sei sfortunato.

Quando si progetta una classe astratta, è possibile chiedersi:

  • Ci sono molte proprietà?
  • Quante classi erediteranno questo? 3? 15? 100?
  • Sto dichiarando qualsiasi metodo astratto (come gli avanzi da implementazioni dell'interfaccia parziale)?
  • Questa astrazione lega insieme due o più classi altrimenti non correlate?

Se non molte classi erediteranno da esso o creerà una relazione dove altrimenti non ci sarebbero, allora è probabile che tu possa fare ciò che stai cercando di fare con i tratti.

Un esempio potrebbe essere Model vs ActiveRecord ; "form vs feature".

  • ActiveRecord può fornire un'impalcatura / implementazione parziale per un'interfaccia CRUD (come una proprietà $table , un metodo static::load($id) , ecc.)
  • Model potrebbe avere funzioni di aiuto integrate o un metodo validate() astratto e non può creare un'istanza autonoma.
  • Non tutti i Models sono ActiveRecords e viceversa.

ActiveRecord sarebbe il migliore come tratto, poiché applica orizzontalmente in tutta l'applicazione. Models invece ha una gerarchia definita e funzionerebbe al meglio come un abstract.

    
risposta data 30.06.2014 - 02:21
fonte
0

Questo è il caso d'uso classico per favore la composizione sull'ereditarietà . Se alcune proprietà sono strettamente collegate, allora mettile in una classe a parte. Quindi hai solo bisogno di una proprietà che faccia riferimento a quella classe invece di avere proprietà ripetute dappertutto. Puoi quindi sbarazzarti della completa gerarchia delle classi.

Inoltre, ricorda che le classi astratte riguardano il comportamento astratto. Se un getter è il comportamento della tua classe, allora potrebbe essere ok avere una classe astratta con un getter (lo stesso vale per setter). Ma non ha più senso dal punto di vista comportamentale avere getter e setter per la stessa proprietà nella stessa classe base, dato che non lascia spazio alle astrazioni comportamentali.

    
risposta data 30.06.2014 - 15:51
fonte

Leggi altre domande sui tag