Arquitectura modular para procesar la tubería

8

Estoy tratando de diseñar la arquitectura de un sistema que implementaré en C ++, y me preguntaba si la gente podría pensar en un buen enfoque o criticar el enfoque que he diseñado hasta ahora.

En primer lugar, el problema general es un proceso de procesamiento de imágenes. Contiene varias etapas, y el objetivo es diseñar una solución altamente modular, de modo que cualquiera de las etapas pueda ser fácilmente intercambiada y reemplazada por un código personalizado (para que el usuario pueda aumentar la velocidad si lo sabe). que cierta etapa está restringida de cierta manera en su problema).

El pensamiento actual es algo como esto:

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);

Esto permitiría a las personas subclasificar input_routines y anular cualquier etapa que quisieran. Dicho esto, he trabajado en sistemas como este antes, y encuentro que las subclases y las cosas predeterminadas tienden a ensuciarse, y pueden ser difíciles de usar, por lo que no estoy mareado acerca de escribir uno por mi cuenta. También estaba pensando en un enfoque más moderno, donde las diferentes etapas (hay 6 o 7) serían parámetros de plantilla predeterminados.

¿Alguien puede ofrecer una crítica del patrón anterior, los pensamientos sobre el enfoque de la plantilla o cualquier otra arquitectura que se me ocurra?

    
pregunta anjruu 16.02.2011 - 17:01

4 respuestas

2

El diseño depende en gran medida de lo que realmente hacen las diferentes etapas. En su mayoría prefiero funciones virtuales puras sobre funciones virtuales no puras (clases abstractas).

Las etapas comunes se pueden agrupar en subclases abstractas. Al derivar de la clase abstracta principal todavía puede ajustar cada etapa, pero al derivar de una subclase puede reutilizar el comportamiento existente que ya está escrito. Tiende a ser menos complicado, como menciona para los métodos virtuales.

Si las diferentes etapas también pueden existir por sí mismas (fuera de toda la tubería), también considere escribir clases para separar este comportamiento.

    
respondido por el Steven Jeuris 16.02.2011 - 17:26
2

Tal vez cree una lista de funtores en una fábrica, que implementa las etapas. Pseudo-código:

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

Los usuarios pueden volver a implementar la fábrica o simplemente manipular la lista de functores. Pseudo-código

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

o

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

Cuando finalice la configuración, puede llamar a cada functor utilizando el resultado del último.

    
respondido por el LennyProgrammers 16.02.2011 - 17:52
0

Eche un vistazo a las mónadas implementadas en Haskell, que pueden darle una buena idea de cómo configurar las cosas. Haskell tiene este tipo de cosas realmente bien.

    
respondido por el Zachary K 16.02.2011 - 17:05
0

Definiría un tipo Intermedio. Todas las imágenes se convertirían a este formato; cada etapa tomaría un Intermedio y devolvería un Intermedio - no el mismo, uno nuevo.

Una etapa sería esta:

Intermediate DoSomething(const Intermediate &i);

Por lo general, evito las soluciones basadas en herencia en general, a menos que sean un mapa bastante obvio del problema, por ejemplo, los objetos en un mundo 3D.

    
respondido por el Paul Nathan 16.02.2011 - 18:46

Lea otras preguntas en las etiquetas