Architettura modulare per la lavorazione della pipeline

8

Sto cercando di progettare l'architettura di un sistema che implementerò in C ++, e mi chiedevo se le persone potessero pensare ad un buon approccio o criticare l'approccio che ho progettato fino ad ora.

Prima di tutto, il problema generale è una pipeline di elaborazione delle immagini. Contiene diverse fasi e l'obiettivo è progettare una soluzione altamente modulare, in modo tale che qualsiasi fase possa essere facilmente sostituita e sostituita con un pezzo di codice personalizzato (in modo che l'utente possa avere un aumento di velocità se sa che un certo stadio è vincolato in un certo modo nel suo problema).

Il modo di pensare attuale è qualcosa di simile a questo:

struct output; /*Contains the output values from the pipeline.*/

class input_routines{
    public:
    virtual foo stage1(...){...}
    virtual bar stage2(...){...}
    virtual qux stage3(...){...}
    ...
}

output pipeline(input_routines stages);

Ciò consentirebbe alle persone di sottoclasse le routine_input e di eseguire l'override di qualsiasi fase volessero. Detto questo, ho già lavorato in sistemi come questo, e trovo che le sottoclassi e le cose predefinite tendano a diventare disordinate e possano essere difficili da usare, quindi non sono elettrizzato a scriverne uno io stesso. Stavo anche pensando ad un approccio più STLish, in cui i diversi stadi (ci sono 6 o 7) sarebbero parametri predefiniti del template.

Qualcuno può offrire una critica del modello di cui sopra, pensieri sull'approccio modello o qualsiasi altra architettura che viene in mente?

    
posta anjruu 16.02.2011 - 17:01
fonte

4 risposte

2

Il design dipende in larga misura da ciò che effettivamente fanno le diverse fasi. Preferisco principalmente funzioni virtuali pure su funzioni virtuali non pure (classi astratte).

Le fasi comuni possono essere raggruppate in sottoclassi astratte. Derivando dalla principale classe astratta è ancora possibile regolare ogni fase, ma derivando da una sottoclasse è possibile riutilizzare il comportamento esistente che è già stato scritto. Tende ad essere meno disordinato, come dici per i metodi virtuali.

Se le diverse fasi possono anche esistere da sole (al di fuori dell'intera pipeline), considera anche di scrivere classi per separare questo comportamento.

    
risposta data 16.02.2011 - 17:26
fonte
2

Magari creare una lista di funtori in una fabbrica che implementa le fasi. Pseudo-codice:

functorFactory() {
  return [ foo(), bar(), baz() ]
}

Gli utenti possono reimplementare la fabbrica o semplicemente manipolare la lista dei funtori. Pseudo-codice

myFactory() {
  return [ foo(), myBar() ]
}

o

myFactory() {
  return functorFactory()[2] = myBar()
}

Al termine dell'impostazione, puoi chiamare ciascun functor utilizzando il risultato dell'ultimo.

    
risposta data 16.02.2011 - 17:52
fonte
0

Dai un'occhiata a Monads implementato in Haskell, che potrebbe darti una buona idea su come impostare le cose. Haskell ottiene questo tipo di cose davvero bene.

    
risposta data 16.02.2011 - 17:05
fonte
0

Definirei un tipo intermedio. Tutte le immagini verrebbero convertite in questo formato; ogni fase prende un intermediario e restituisce un intermediario - non lo stesso, uno nuovo.

Uno stage sarebbe questo:

Intermediate DoSomething(const Intermediate &i);

Solitamente evito le soluzioni basate sull'eredità in generale, a meno che non siano una mappa abbastanza ovvia sul problema, ad es. oggetti in un mondo 3D.

    
risposta data 16.02.2011 - 18:46
fonte

Leggi altre domande sui tag