Background: la mia azienda sta lavorando con i sistemi di telecamere. All'inizio abbiamo costruito la nostra applicazione attorno a diversi modelli / configurazioni di essi, che consistevano in diverse macchine fotografiche o procedure per acquisire e combinare i dati acquisiti. Tuttavia, eravamo sempre limitati ad avere un singolo sistema attivo nella nostra applicazione. Un giorno abbiamo avuto l'idea di collegare più sistemi di telecamere per acquisire più dati contemporaneamente in periodi di tempo più brevi. Da allora, abbiamo problemi a rappresentarlo in modo pulito nel nostro software.
Concettualmente abbiamo questo design molto semplificato:
class ICamSystem
{}
class SomeCamSystemImpl : public ICamSystem
{}
class MultiCamSystem
{
std::vector<ICamSystem> cam_systems;
}
La grande decisione è se dobbiamo o meno avere MultiCamSystem derivare e implementare ICamSystem. A prima vista questo sembra molto ragionevole perché in teoria un MultiCamSystem dovrebbe supportare praticamente lo stesso insieme di operazioni di ICamSystem. In effetti, la maggior parte delle implementazioni di MultiCamSystem fa semplicemente inoltrare una chiamata di metodo a tutti i suoi sistemi di telecamere composite. Decidere contro questo significa anche che dovremmo gonfiare ogni singolo sito di chiamata con una distinzione di casi tra avere un singolo sistema di telecamere o un sistema di telecamere multiple. D'altra parte, seguendo il Principio di sostituzione di Liskov un MultiCamSystem non è un ICamSystem e ha portato a tutti i tipi di problemi di follow-up. Due esempi molto semplici:
ICamSystem::set_parameter
ha un'implementazione molto naturale per un sistema di telecamere: o riesce e imposta il parametro o fallisce con un'eccezione. Su un sistema a più telecamere vorrei intuitivamente implementarlo in questo modo:
MultiCamSystem::set_parameter( const Param& p )
{
for(auto* cs : cam_systems)
cs->set_parameter(p)
}
Ma in alcuni casi questo non ha senso perché ogni sistema di telecamere potrebbe avere intervalli diversi di parametri validi / accettabili. Ad esempio, l'impostazione dell'esposizione in questo modo molto probabilmente non ha molto senso perché, a causa delle condizioni di illuminazione esterne, devo spesso regolarle singolarmente per ciascun sistema, il che rompe la mia astrazione dall'avere un singolo sistema di telecamere che accetta un singolo tempo di esposizione. Devo anche preoccuparmi della gestione degli errori, ad esempio quando un'operazione fallisce su un sottoinsieme dei sistemi di telecamere.
Data ICamSystem::acquire_data() or
SystemID ICamSystem::getID()
Prima, avevo solo un singolo valore di ritorno da un metodo. Con un sistema multi-camera questo deve essere piuttosto:
std::vector<Data> ICamSystem::acquire_data() or
std::vector<SystemID> ICamSystem::getID()
così di nuovo questo rompe la mia astrazione. Ovviamente potrei cambiare la firma nell'interfaccia astratta e fare in modo che i singoli sistemi di telecamere restituiscano un vettore di dimensione 1. Ma sembra sconsigliabile mettere a punto un'interfaccia generica e perfettamente ragionevole per implementazioni specifiche di esso.
Quale è un modo migliore per rappresentarlo allora?