Come evitare una quantità pazzesca di interfacce nell'interfaccia utente con l'iniezione delle dipendenze?

9

problema
Recentemente ho letto molto sul fatto che Singletons sta male e su come l'iniezione di dipendenza (che intendo come "usare le interfacce") sia migliore. Quando ho implementato parte di questo con callbacks / interfacce / DI e aderendo al principio di segregazione dell'interfaccia, ho finito con un bel pasticcio.

Le dipendenze di un genitore dell'interfaccia utente in cui fondamentalmente si univano quelle di tutti i suoi figli, quindi più la gerarchia era un elemento dell'interfaccia utente, più il suo costruttore era gonfio.

Fino in cima alla gerarchia dell'interfaccia utente era una classe Application, contenente le informazioni sulla selezione corrente e un riferimento a un modello 3d che deve riflettere le modifiche. La classe dell'applicazione stava implementando 8 interfacce, e questo è stato solo un quinto dei prodotti (/ interfacce) a venire!

Attualmente lavoro con un singleton che tiene la selezione corrente e gli elementi dell'interfaccia utente che hanno una funzione per aggiornarsi. Questa funzione scorre lungo la struttura dell'interfaccia utente e gli elementi dell'interfaccia utente quindi accedono alla selezione corrente singleton secondo necessità. Il codice mi sembra più pulito in questo modo.

Domanda
Forse un singleton è appropriato per questo progetto?
In caso contrario, c'è un difetto fondamentale nel mio modo di pensare e / o nell'implementazione di DI che lo rende così ingombrante?

Ulteriori informazioni sul progetto
Tipo: Carrello per gli appartamenti, con campane e fischietti Dimensione: 2 mesi uomo per il codice e l'interfaccia utente Manutenzione: nessun aggiornamento in corso, ma forse "versione 2.0" successiva
Ambiente: utilizzo di C # in Unity, che utilizza un sistema Componente entità

In quasi tutti i casi, l'interazione dell'utente innesca diverse azioni. Ad esempio, quando l'utente seleziona un elemento

  • la parte dell'interfaccia utente che mostra che l'elemento e la sua descrizione devono essere aggiornati. Per questo, ha anche bisogno di ottenere alcune informazioni da un modello 3d per calcolare il prezzo.
  • più in alto l'interfaccia utente, il prezzo totale complessivo deve essere aggiornato
  • è necessario chiamare una funzione corrispondente in una classe su un modello 3d per visualizzare le modifiche lì
posta R. Schmitz 26.04.2016 - 12:49
fonte

2 risposte

4

Penso che la domanda sia un sintomo, non una soluzione.

I recently read a lot about Singletons being bad and how dependency injection (which I understand as "using interfaces") is better. When I implemented part of this with callbacks/interfaces/DI and adhering to the interface segregation principle, I ended up with quite a mess.

Una soluzione alla ricerca di un problema; questo e fraintendimenti probabilmente sta corrompendo il tuo progetto. Hai letto questa domanda SO su DI vs Singleton, concetti diversi o no? Ho letto che come semplicemente avvolgendo un singleton quindi il cliente non ha a che fare con un singleton. It.is.just.good.old.encapsulation. Penso che sia azzeccato.

the further up the hierarchy a UI element was, the more bloated its constructor was.

Costruisci i bit più piccoli prima di passarli nel costruttore della cosa a cui appartengono e passa quella cosa più grande nel costruttore della prossima cosa più grande ...

Se hai problemi di costruzione complessi, usa lo schema di fabbrica o di costruzione. La linea di fondo è che la costruzione complessa viene inserita nella propria classe per mantenere le altre classi pulite, pulite, comprensibili, ecc.

The application class was implementing 8 interfaces, and this was only roundabout a fifth of the products (/ interfaces) to come!

Sembra l'assenza dell'estensione. Manca il design principale e tutto viene riempito dall'alto. Ci dovrebbero essere più bottom up di costruzione, composizione ed ereditarietà.

Mi chiedo se il tuo design sia "molto pesante". Sembra che stiamo cercando di fare in modo che una classe sia tutto o qualcosa che potrebbe essere. E il fatto che si tratti di una classe UI, non di un dominio aziendale, mi fa davvero meravigliare della separazione delle preoccupazioni.

Rivisita il tuo design sin dall'inizio e sii sicuro che esiste un'astrazione di prodotto solida e di base che può essere costruita per rendere più complesse o diverse produzioni di categoria. Allora è meglio avere collezioni personalizzate di queste cose in modo da avere un posto dove mettere la funzionalità di "livello di raccolta", come quella di "3 ° modello" che menzioni.

... 3d model which needs to reflect changes.

Gran parte di ciò può rientrare nelle classi di raccolta personalizzate. Potrebbe anche essere una struttura di classe indipendente a causa della profondità e della complessità. Queste due cose non si escludono a vicenda.

Leggi informazioni sul modello di visitatore. È l'idea di avere mandrini interi di funzionalità collegati in modo astratto a tipi diversi.

Progettazione e DI

Il 90% di tutte le iniezioni di dipendenze che farai mai è il passaggio dei parametri del costruttore. Così dice il quy che ha scritto il libro . Progetta bene le tue classi ed evita di inquinare quel processo di pensiero con una vaga idea di dover usare un contenitore DI-cosy. Se ne hai bisogno, il tuo design te lo suggerirà per così dire.

Concentrati sulla modellazione del dominio di acquisto di appartamenti.

Evita l'approccio al design di Jessica Simpson : "Non so assolutamente cosa significhi, ma io lo voglio. "

I seguenti sono solo sbagliati:

  • Dovrei usare le interfacce
  • Non dovrei usare un singleton
  • Ho bisogno di DI (qualunque cosa sia)
  • Dovrei usare la composizione, non l'ereditarietà
  • Dovrei evitare l'ereditarietà
  • Devo usare i pattern
risposta data 02.05.2016 - 19:48
fonte
3

"Classe gerarchia" è un po 'una bandiera rossa. Ipotetico: una pagina web con 5 widget. La pagina non è un antenato di nessuno dei widget. Potrebbe contenere un riferimento a quei widget. Ma non è un antenato. Invece dell'erarchia di classe, prendi in considerazione l'uso della composizione. Ognuno dei 5 widget può essere costruito da solo, senza riferimento agli altri widget o alla pagina principale. La prima pagina viene quindi costruita con informazioni sufficienti per creare una pagina di base e il layout degli oggetti widget (Raccolta) che gli vengono passati. La pagina è responsabile del layout, ecc., Ma non per la costruzione e la logica dei widget.

Una volta che usi la composizione, DI è il tuo migliore amico. DI ti consente di scambiare ogni widget per qualsiasi versione o tipo di widget che definisci in DI. La costruzione dei widget viene catturata nel DI e separata dalla pagina principale. Forse anche la composizione della collezione può essere definita nel tuo DI. La prima pagina esegue il layout in base ai widget passati, come dovrebbe. Non sono necessarie modifiche al costruttore della pagina principale. La pagina principale richiede solo la logica per eseguire il layout dei widget e passare informazioni a / da widget in base alle interfacce definite.

Invece di far passare gli ascoltatori su e giù per la catena di composizione, iniettare una raccolta di ascoltatori per quei widget che ne hanno bisogno. Inietta la raccolta in un editore in modo che possa pubblicare nella raccolta. Inietta la raccolta negli ascoltatori in modo che possano aggiungersi alla raccolta. La collezione attraversa tutti gli oggetti della catena di composizione.

    
risposta data 26.04.2016 - 15:14
fonte

Leggi altre domande sui tag