Vraťme se, k začátku diskuse. Tam já jsem tvrdil, že jeden konkrétní navržený interface je dobře, protože je velmi špatně rozšiřitelný. A když ho budu chtít rozšířit. Jestli jste to pochopil jako kritiku OOP, tak si to přečtěte ještě jednou, nebyla to kritika OOP, ale kritika využití dědičnosti na místě, kam prostě dědičnost nepatří. To není nic proti OOP, to je naopak pro OOP. A demonstroval jsem, že z určitých důvodů je ten návrh špatně.
Vy jste na to odpověděl, že není špatně, protože to jde "opravit" pomocí nového rozhraní. A já pouze tvrdím, že to sice jde, že to je někdy i nejlepší řešení, ale že bylo špatně, když se to neudělalo pořádně hned.
A abych se nedržell u země, vždycky se dá vyrobit úplně nová hierarchie.
Ano jde. Jde psát program pomocí spousty goto. Jde o to, jak bude takový program čitelný. A rozhodně program s méně univerzálními enterfacy bude čitelnější, než program, kde je pro každou věc nadefinovaný nový interface.
Interface je abstrakce, zobecnění. Pokud tedy pro každou věc nadefinuji nový interface, tak kde je ta abstrakce?
Nebo co komu vadí, když můj myslivec bude mít takovou deklaraci
No vadí tomu spousta věcí. Např. chci objekt na lov. Mám tam poslat IMyslivce,nebo
IMyslivce2?
Chci napsat nové rozhraní na kontrolu všech psů (např. úředníkem). Mám dvě možnosti: První je využít existující rozhraní. Tady ale místo jednoho rozhraní IMajitelZvirat musím kontrolovat rozhraní IMyslivec, IMyslivec2, IKlientVeterinare (a deset dalších).
Navíc, mezi těmi rozhraními není vztah, co když přijde někdo implementující IMyslivec i IKlientVeterinare? Mám kontrolovat objekt pouze skrze jedno z nich, nebo skrze obě? Jak vým, jestli myslivec chodí k veterináři s kočkou, nebo svým mysliveckým psem? Ve výsledku napíšu hromadu zbytečnýho kódu řešící existenci deseti duplicitních rozhraní.
Druhá možnost je napsat nové rozhraní IKontrolovanýClovek. Jenže todle rozhraní nikdo neumí, takže nic nezkontroluji, aniž bych přepsal všechny objekty, které chci kontrolovat - a právě proti tomu brojíte.
No a pak je třetí možnost, že mam v kódu pořádek, IMyslivec byl od začátku poděděnej od IMajitelZvirat, toto rozhraní používá i veterinář a když chci napsat kontrolu úředníkem, opět využiji to samé rozhraní IMajitelZvirat.
Toto řešení je IMHO nejlepší, nejčistší, s nejmenší pravděpodobností výskytu chyb. Také nejvíce odpovídá principu OOP, protože podporuje reusability.
Vy neustále dokazujete, že se umíte vyhnout multi-interfaců
Už jsem tu jednou psal, nevylučuji, že to řešení s dynamic_castem nebude někdy nejlepší možné. Ani nevylučuji, že se mi návrh nepovede a multi-interfacům se nevyhnu. To ale přeci nepovyšuje bastl na standard.
Když chci přejít řeku a vím, že se tam nebudu vracet, stačí mi doprostřed naházet šutry a přeskákat. To ale neznamená, že mohu prohlašovat, že ty naházené kameny jsou most. Je to bastl - i když v dané situaci nejlepší řešení.
Stejně tak když na 1GB harddisku na data udělám 100MB partition, protože si blbě přečtu velikost - tak pak může být nejlepším řešením udělat ze zbylého místa druhou partition (např. proto, že data nemám kam odzálohovat). To ale přeci neznamená, že by to měl být standardní postup, nebo že řešení se dvěma partition je nejlepší.
co když místo čísel budem sčítat matice, nebo rovnice?
Právě proto existují určité zásady, jak navrhovat rozhraní - aby se minimalizovala práce při rozšiřování funkčnosti programu. A podle těchto zásad jdou rozhraní posuzovat. Ano, je možné, že budu mít problém, i když ty zásady dodržím, ale ten problém nebude tak často a bude zpravidla daleko jednodušeji řešitelný.
Jednu z těchto zásad sem postnul Tiger. A jelikož IMyslivec tuto zásadu porušuje, jde toto rozhraní označit jako špatně navržené.