Krásné jak víme, co je správné, aniž bysme znali vlastně zadání a původní návrh.
V tom je totiž krása OOP - chyby návrhu každého objektu se dá posoudit, aniž by bylo třeba znát "okolí".
(Samozřejmě okolí je potřeba pro to, aby se posoudila vhodnost toho interfacu pro interakci s okolím, ale toto posuzování má přijít teprve po posouzení správnosti daného rozhraní jako takového).
Tohle v původním návrhu není.
V původním návrhu je myslivec. Může myslivec vlastnit více psů. Ano, takových myslivců je spousta. Takže popisovat ho rozhraním, které umožní pouze jednoho psa je špatně.
Zato vaše komponentní aplikace má takový úspěch, že každé myslivecké združení má vlastní implementaci myslivce.
Ne, v mém pojetí se všichni lidi, kteří používají dané rozhraní pořádně zamyslí, navrhnou rozhraní tak, aby ho už pokud možno nebylo nutné modifikovat a používají ho. Samozřejmě ne vždy se to povede, ale protože já považuji některé návrhy rozhraní za apriori špatné, nestane se mi totéž, co Tobě:
Ve Tvém návrhu se nejdřív nabastlí myslivec s jedním psem, pak někdo přijde na to, že potřebuje myslive s více psy, tak nadefinuje druhé rozhraní, někdo další zjistí, že potřebuje myslivce s více flintami, nadefinuje nové rozhraní, pak někdo zjistí, že potřebuje myslivce s více dýmkami... nové rozhraní.....
Já, protože vím, že apriori je blbina myslivec s jednou flintou, psem či dýmkou (vždy jich může mít víc) tak nemusím žádná nová rozhraní definovat, protože už původní rozhraní funguje správně.
No už se stalo. Asi by to člověk měl smazat a začít znova? Nebo s tím praštit úplně :-D
Jo, člověk někdy udělá chybu, to je normální. Holt si prostě přizná: aha, při návrhu rozhraní myslivec jsem udělal pořádnou botu. A musí to buď přepsat (upravit rozhraní myslivce) nebo zaflikovat (udělat rozhraní myslivec2). Někdy je lepší to, někdy to, podle toho, jak je aplikace velká, kde všude se rozhraní používá, jak často se do ní šahá (čím více, tím se víc vyplatí čistší kód) atd...
U většího projektu může být dobrá cesta nadefinovat nové rozhraní, staré prohlásit za obsolete a pomalu (když se zrovna upravuje danej kus) ho z aplikace odstraňovat. Narozdíl od udržování dvou rozhraní se časem kód zas pročistí a přitom náklady budou srovnatelné (do budou spíš nižší, protože kód bude čistší).
Já neříkám, že řešení s dynamic_castem je vždy špatně. Říkám, že to, že je ho nutné použít ukazuje, že je něco špatně: většinou ten původní návrh.
---
Ve zbytku postu polemizuješ úplně s něčím jiným, než co tvrdím. Pokud už se chyba STALA, tedy pokud existuje rozhraní myslivec s jedním psem, samozřejmě může být levnější a tedy lepší řešení to opravit pomocí rozhraní myslivec2.
Co tvrdím je, že při PŮVODNÍM návrhu aplikace byla chyba udělat myslivce s jedním psem, pokud byla alespoň trochu reálná možnost, že myslivec může mít psy dva. Protože to při dalším vývoji aplikace způsobí to, že přes hranice budou chodit nenaočkovaní psi (a nebo drahý refaktoring).
---
Myslím, že to, v čem se lišíme je pragmatismus kontra idealismus. Vy tvrdíte, že pokud rozhraní vyhovuje pro dané účely v daném čase, je dobře.
Já tvrdím, že rozhraní má dobře popisovat daný objekt. Pokud popisuj dobře daný objekt, pak bude vyhovovat: a to nejen pro daný účel v daný čas, ale pro všechny účely a vždy.
Vzhledem k tomu, že jedním ze základním principů OOP je znovupoužitelnost, myslím, že můj pohled je bližší k filosofii OOP než Tvůj.
Já svého myslivce mohu použít jak při honu, tak u veterináře, tak i pro přechod hranic. Tvůj myslivec se hodí jen na ten hon (a to ještě nesmí sestřelit dvě kachny najednou, což se brokovnicí dosti často povede)...
Samozřejmě ne vždy lze postihnout úplně všechny možnosti. Ale např. v případě myslivce se psem je rozdíl v náročnosti implementace marginální (mohu tam dát ještě metodu getNejakyPes(), takže používat se to bude úplně stejně, jen holt místo pesPtr bude ve vlastnostech std::list<pesPtr>) ale v budoucnu to ušetří hafo problémů.