I did something similar to the following code:
void launchPipeline(IQueryFactory & queryFactory, IQuerySender &querySender, IValidateResponse &responseValidator)
{
std::unique_ptr<IQuery> query = queryFactory.getInstance();
/*
auto a,b,c = querySender.send(query);
//we just get a lot of params from that function
*/
if(responseValidator.validate(query, a, b, c)
{
//do something
}
}
class IValidateResponse
{
public:
virtual bool validate(IQuery & query, int a, int b, int c) = 0;
};
class QueryAValidator
{
public:
bool validate(IQuery & query, int a, int b, int c) override
{
const auto & queryA = dynamic_cast<const QueryA &>(query);
//do something
}
};
It works perfectly fine because matching types of IQueryFactory and IValidateResponse are injected in. But I was wondering if this could be avoided in some fancy way?
I was thinking about QueryVisitor but I'm not sure how to implement it, the visit function would require to take a, b, c params which would look weird on IQuery interface, like query.accept(visitor, a, b, c).
Or I could store these params inside the visitor, but that still doesn't feel smooth, especially when it comes to writing tests. For now I have so called "validators tests" where I simply put fake response and test the concrete Validator class, adding visitor to that would make them more complicated.
How would you solve that?