Estou tentando projetar a arquitetura de um sistema que implementarei em C ++ e fiquei pensando se as pessoas poderiam pensar em uma boa abordagem ou criticar a abordagem que eu projetei até agora.
Primeiro de tudo, o problema geral é um pipeline de processamento de imagens. Ele contém vários estágios, e o objetivo é projetar uma solução altamente modular, para que qualquer um dos estágios possa ser facilmente trocado e substituído por um código personalizado (para que o usuário possa ter um aumento de velocidade, se souber) que um certo estágio é restringido de uma certa maneira no seu problema).
O pensamento atual é algo como isto:
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);
Isso permitiria que as pessoas subclassificassem as regras de entrada e substituíssem o estágio que desejassem. Dito isso, já trabalhei em sistemas como esse antes e acho que a subclasse e o material padrão tendem a ficar confusos e podem ser difíceis de usar, por isso não estou tonto em escrever um. Eu também estava pensando em uma abordagem mais STLish, na qual os diferentes estágios (existem 6 ou 7) seriam parâmetros de modelo padrão.
Alguém pode oferecer uma crítica ao padrão acima, pensamentos sobre a abordagem do modelo ou qualquer outra arquitetura que lhe vier à mente?
fonte
Respostas:
O design é altamente dependente do que os diferentes estágios realmente fazem. Prefiro principalmente funções virtuais puras do que funções virtuais não puras (classes abstratas).
Os estágios comuns podem ser agrupados em subclasses abstratas. Ao derivar da classe abstrata principal, você ainda pode ajustar todos os estágios, mas ao derivar de uma subclasse, é possível reutilizar o comportamento existente que já está escrito. Tende a ser menos confuso, como você menciona nos métodos virtuais.
Se os diferentes estágios também puderem existir sozinhos (fora de todo o pipeline), considere também escrever classes para separar esse comportamento.
fonte
Talvez crie uma lista de functores em uma fábrica, que implementam os estágios. Pseudo-código:
Os usuários podem reimplementar a fábrica ou apenas manipular a lista de functores. Pseudo-código
ou
Quando a instalação estiver concluída, você poderá chamar cada functor usando o resultado do último.
fonte
Dê uma olhada nas Mônadas, conforme implementadas em Haskell, que podem lhe dar uma boa idéia de como configurar as coisas. Haskell acertou esse tipo de coisa.
fonte
Eu definiria um tipo intermediário. Todas as imagens seriam convertidas para este formato; cada estágio pegaria um intermediário e retornaria um intermediário - não o mesmo, um novo.
Um estágio seria o seguinte:
Intermediate DoSomething(const Intermediate &i);
Geralmente evito soluções baseadas em herança em geral, a menos que sejam um mapa bastante óbvio para o problema, por exemplo, objetos em um mundo 3D.
fonte