È appropriato utilizzare l'ereditarietà per impedire la duplicazione del codice della logica per un controllo utente?

2

Supponiamo di avere due o più implementazioni UserControl con implementazioni molto diverse ma quasi identiche a code-behind. Una strategia per evitare la duplicazione del codice è la seguente:

  1. Cambia ogni UserControl per ereditare da una nuova classe astratta, AwesomeUserControl
  2. Sposta tutto il codebehind da ogni UserControl a AwesomeUserControl ( AwesomeUserControl non ha un file ascx).
  3. Aggiungi getter astratti a AwesomeUserControl per qualsiasi controllo dal file ascx degli UserControls originali.
  4. Implementa questi getter in ogni UserControl .

Questa strategia funziona estremamente bene ed è facile da mantenere. Tuttavia, introduce anche codice stupido di scaffolding; ogni nuova implementazione di AwesomeUserControl ha un gruppo di getter per agganciare AwesomeUserControl agli elementi dell'interfaccia utente all'interno del nuovo controllo. Ogni volta che mi ritrovo a utilizzare una strategia che richiede codice di ponteggio incollato alla copia, mi preoccupo di fare qualcosa di sbagliato. Anche se ha un bell'effetto di non riuscire a compilare se mancano gli elementi dell'interfaccia utente (al contrario di saltare il codice dello scaffolding a favore della riflessione e della denominazione richiesta).

Questo uso dell'ereditarietà è ragionevole?

    
posta Brian 21.04.2014 - 23:27
fonte

3 risposte

1

Implementazioni estremamente diverse? Sembra un cattivo candidato per una classe genitore astratta comune, non credi?

Altrimenti, devi essere più preciso di AwesomeUserControl . Quali sono i controlli esatti che condividono la stessa logica? Quale logica è condivisa?

Come esempio, ecco un copia-incolla da una risposta che ho scritto qualche giorno fa:

  • Either two classes are related (for example both Cat and Dog can be fed, and it takes the same steps to feed them both, except the food which will change), in which case, create an inheritance (in my example, a parent class Pet),

  • Or two classes are unrelated, and just rely on the same method. For example, WebRequest class may rely on GetSlug¹ to find the slug of the current request; Customer may also rely on GetSlug to normalize the name of the customer for further search purposes. However, WebRequest and Customer are totally unrelated, and it makes no sense to create a common object for those classes.

    Here, the solution would be to call a common method from those two classes, by instantiating the third class containing this method. For example, both RequestUri and CustomerName may become objects implementing ISlug interface.

    
risposta data 21.04.2014 - 23:43
fonte
1

Devo dire che dipende molto dalle due classi.

Se hai due classi che condividono molti degli stessi metodi e condividono molte delle stesse proprietà e campi, creerei una classe genitore. L'ereditarietà è probabilmente la soluzione migliore qui.

Un'interfaccia è bella, ma non penso che ti aiuterà con quello che vuoi, il che credo tu stia cercando la riduzione del codice.

Non sono d'accordo con l'esempio dell'interfaccia ISlug di MainMa, ma ancora una volta, ciò dipende dall'implementazione degli oggetti. Le interfacce sono ottime, ma non è necessario crearne una solo perché due classi condividono gli stessi nomi e parametri dei metodi.

Se pubblichi un po 'di più su cosa fanno i tuoi due pulsanti, e forse solo le funzioni e i campi / proprietà che condividono, sarebbe un po' più illuminante per la situazione.

    
risposta data 22.04.2014 - 00:16
fonte
-1

This strategy works extremely well and is easy to maintain. However, it also introduces stupid scaffolding code; every new implementation of AwesomeUserControl has a bunch of getters to hook

Accedi direttamente ai controlli. Nella classe astratta:

#Region "WebControls - Objects must be on derived aspx and deleted from .asx.designer"
  Protected WithEvents SomeDiv As Global.System.Web.UI.HtmlControls.HtmlGenericControl
  Protected WithEvents SomeLabel As Global.System.Web.UI.WebControls.Label
  Protected WithEvents SomeLinkButton As Global.System.Web.UI.WebControls.LinkButton
  ...
#End Region
    
risposta data 14.01.2015 - 13:04
fonte

Leggi altre domande sui tag