Qual è l'Object Design / Architecture corretto per il seguente scenario?

3

Sto sviluppando alcuni controlli personalizzati in un linguaggio orientato agli oggetti (usando Swift / Cocoa, ma questa è una domanda agnostica della tecnologia). In particolare, ho un insieme di pulsanti orizzontali e verticali che si comportano in modo molto simile, tranne per il fatto che uno è orientato verticalmente e l'altro orizzontalmente.

La mia domanda: qual è il modo corretto di strutturare queste due "cose" nel mio progetto:

Dovrei avere una classe genitore (astratta) con funzionalità comuni e quindi due classi concrete derivate per le specifiche necessarie per l'orizzontalità rispetto alla verticalità. Questo sembra il più corretto, ma dato che l'oggetto è composto da altri oggetti, la proliferazione di tutta la gerarchia della vista si sposterà verso il basso.

In alternativa, dovrei progettare una classe altamente generalizzata che abbia una proprietà per l'orientamento e quindi molta logica if / switch nel codice per guidare il comportamento basato su questo. Sembra un odore di codice.

Basta andare e creare due classi separate simili ma tecnicamente non correlate e basta fare una digitazione un po 'più ripetuta. Poiché così tante cose sono guidate dall'orientamento, questo sembra quasi più semplice di 1 sopra.

O c'è un'altra alternativa?

Altri esempi canonici in cui ciò si presenterebbe potrebbero essere orizzontali o verticali:     - scrollers     - impilare pannelli

Per tentare di chiarire in merito agli obiettivi e ai requisiti di progettazione, vorrei che la domanda rispondesse in termini di come Apple Software Architects avrebbe potuto avvicinarsi alla classe NSScrollView (o come qualsiasi grande organizzazione potrebbe avvicinarsi al codice di libreria UI simile con "mirror" orizzontale e componenti verticali).

La risposta influisce su diverse classi verticali e orizzontali correlate che aggregano questi pulsanti rispettivamente in righe e colonne poiché le stesse righe e colonne sono molto simili, salvo per l'orientamento verticale vs orizzontale.

    
posta Sam 29.12.2014 - 15:43
fonte

3 risposte

1

Come nota anticipata, non ho familiarità con il funzionamento dei componenti della UI di Apple e ho soprattutto esperienza con Qt. Questo potrebbe influenzare l'applicabilità della mia risposta.

Vorrei iniziare con un set di widget neutri all'orientamento, ma che possono essere naturalmente utilizzati dove ci si aspetta un widget specifico dell'orientamento. Ad esempio un pulsante in cui entrambe le dimensioni possono essere impostate come dimensione fissa o allungamento e una griglia con più righe e colonne. Queste sono classi concrete che possono essere utilizzate così com'è.

Con questi widget agnostici di orientamento, un pulsante verticale è solo un pulsante con una larghezza (relativamente piccola) di dimensioni fisse. E una fila è solo una griglia con una sola riga.
Come realizzarlo dipende in gran parte da come viene costruita l'interfaccia utente.

  • Se l'interfaccia utente è per lo più codificata a mano, puoi creare classi derivate specifiche dell'orientamento che non fanno altro che impostare i valori predefiniti appropriati delle loro classi di base agnostiche di orientamento. Una classe VerticalButton avrebbe solo un costruttore per impostare la larghezza del pulsante come valore fisso.
    Ciò non impedisce a qualcuno di cambiare la larghezza di essere variabile, ma quello sarebbe il loro errore.
  • Se l'interfaccia utente è per lo più generata da un designer grafico, esaminerei la possibilità che il progettista fornisca i widget in più gusti (orizzontale, verticale e orientamento-agnostico) che istanziano ciascuno la stessa classe con impostazioni diverse. br> Se fallisce, posso sempre tornare alla prima opzione.

Solo se il widget specifico dell'orientamento richiede un comportamento che non può essere fornito dalla variante agonostica dell'orientamento, prenderemo in considerazione la creazione di una classe a tutti gli effetti (con più di un costruttore) per il widget specifico dell'orientamento.
Ad esempio, se il testo su un pulsante verticale deve essere ruotato, ma la normale classe di pulsanti non supporta la rotazione del testo.

    
risposta data 29.12.2014 - 17:04
fonte
2

Rispondendo in modo molto astratto e indipendente dalla tecnologia / struttura, il mio modo di pensare è il seguente

  • Ciò che un controllo della GUI è (cioè volume su, volume giù) non equivale a come è posizionato in una finestra (una cornice di riferimento visivo).
  • Quindi separa la funzionalità di lay-out dai controlli stessi.
  • Utilizzare una factory per creare vari gestori di layout per i controlli (Control può essere un'interfaccia comune a tutti gli strumenti di controllo o fornisce - suggerisco di usare la composizione - e fornisce informazioni come richiesto dal gestore di layout. larghezza o altezza preferite, in modo simile il gestore di layout potrebbe voler indicare al controllo / componente che è ora in un layout orizzontale, quindi le dimensioni sono così .. ecc.)
  • in questo caso un layout LayoutFactory.createHorizontalLayoutManager (). (Controlli elenco)

Che cosa facilita questo

  • in futuro hai solo bisogno di modificare / aggiungere / fabbriche o metodi al loro interno per creare più opzioni di layout.
  • LayoutFactory.createHorizontalLayoutManager (). layout (controlli List) è un controllo (vari controlli come Button, ScrollBar..etc) agnostico. Semplicemente come impaginare un componente / controllo.
  • I controlli stessi sono agnostici per il dispositivo di destinazione (telefono, TV, BillBoards, Laptop..etc) .. che le informazioni possono essere incorporate nel gestore di layout (ancora meglio, un'implementazione concreta di un'interfaccia Device richiede un gestore di layout e saprebbe cosa significa un layout orizzontale in quel particolare dispositivo e lo rende di conseguenza)
risposta data 29.12.2014 - 19:49
fonte
1

two derived concrete classes for the specifics needed for horizontal-ness vs vertical-ness. This feels the most correct

Bene, per me questo sembra per lo più sbagliato. Il tuo pulsante può avere una dozzina di proprietà o più come l'orientamento, ad esempio potrebbe essere ridimensionabile, avere un colore specifico, potrebbe essere etichettato con un'immagine, testo o entrambi e così via. Se intendi creare derivazioni per ogni proprietà, anche quando ti limiti alle proprietà che non cambiano nel corso della durata dell'oggetto, avrai bisogno di una derivazione aggiuntiva per ogni proprietà combinata (ad esempio, VerticalResizableImageButton, HorizontalResizableImageButton, VerticalResizableTextButton , HorizontalResizableTextButton, ognuno di quelli anche in una variante non ridimensionabile e così via). Immaginate quante diverse derivazioni significheranno alla fine - ogni nuova proprietà moltiplicherà il numero di derivazioni necessarie per un fattore. Non penso che sia fattibile.

should I design one highly generalised class that has a property for orientation and then a lot of if/switch logic in the code to drive behaviour

Vorrei provare a progettare una classe altamente generalizzata che abbia una proprietà per l'orientamento, ma il minor numero possibile di logica condizionale . Se la parte del codice che dipende dall'orientamento finisce in molte istruzioni if / else, può probabilmente essere incapsulata in uno o più oggetti strategia, che vengono inizializzati una volta nel costruttore di pulsanti. Ad esempio, "DragStrategy" (con classi derivate "VerticalButtonDragStrategy" e "HorizontalButtonDragStrategy") per il controllo del ridimensionamento del trascinamento.

    
risposta data 29.12.2014 - 18:37
fonte

Leggi altre domande sui tag