Jste zastánci OOP programování?

D.A. Tiger

  • ****
  • 486
  • Tygr, který žere tučňáka ;-)
    • Zobrazit profil
    • E-mail
Re: Jste zastánci OOP programování?
« Odpověď #105 kdy: 11. 12. 2010, 00:58:38 »
důkaz je vidět zrovna ve vývoji linuxu. Místo toho, aby se zachovala nějaká základní kompatibilita, tak každý jádro je jiný, po binární stránce úplně, po zdrojákový stránce sice méně často, ale i tak to znamená, že staré ovladače s novým jádrem prostě nepřeložím. Nové ovladače nejsou (autor zaniknul, nebo se věnuje něčemu jinému). žádný patch mi nepomůže, neboť  bych si ho musel napsat sám. A to jen proto, že Linus neuznává OOP, a to ani z pohledu techniky programování, když už to musí psát v Cčku a jako Vy, trvá na tom, že stará rozhraní se musí aktualizěovat a navazující moduly se prostě musí přepsat.

Už zase? Linux a C++ je Vaše oblíbené téma, že ano? ;D

otázka kompatibility není o OOP (ať už jej Linus uznává, či ne), ale např. o tom, zda je výhodné tu kompatibilitu sebou nést nebo ne. Navíc všechno je to úhlu pohledu.

Vemte v potaz, že kernel se vyvíjí neuvěřitelně rychle. Nové technologie, podpora nového hardware, nové funkčnosti. K tomu se musí odebírat ty které se neosvědčily, nebo jsou zastaralé (já netvrdím, že je to ideální, ale dělají to lidé a podle mě jim to  jde docela dobře - ve srovnání s konkurencí). Dovedete si představit ten bordel, kdyby jste chtěl v takovém stavu dneska zpětnou kompatibilitu třeba s prvními jádry řady 2.6?

A to se pro jistotu nezmiňuji ani o tom sajrajtu, co by vznikal ( zbytečně a na systémové úrovni k tomu), kdyby se řešila každá chybějící funkčnost, nebo chybný návrh, pouze způsobem který navrhujete výše... 

A navíc, funguje to - už víc než dvacet let.... ;)
« Poslední změna: 11. 12. 2010, 01:27:39 od D.A. Tiger »


ondra.novacisko.cz

Re: Jste zastánci OOP programování?
« Odpověď #106 kdy: 11. 12. 2010, 01:36:57 »
To že tu vrstvu oddělíte do externích modulů, či jakkoliv jinak, však neřeší základní nepříjemnost celého tohoto postupu, a to tu že celou věc znepřehledňuje, zanáší do ní spoustu nových stavů a potencionálních chyb. Vy se v tom možná vyznáte, ale jakmile někdo projekt převezme po Vás, může si jít hodit smyčku (bez urážky, nemyslím tím nic špatného směrem k Vám, vidím to prostě tak i z vlastní zkušennosti).

Celé to připomíná přístup javovských programátorů, kde si vezmete jednu konkrétní funkci z jedné konkrétní knihovny a než se dostanete k tomu co a jak to dělá, prolezete mraky dalších knihoven, vrstev a nadstaveb... A to je špatně (bez ohledu na to zda to někdo řeší či ne, a že to někoho určitě bude zajímat, na to vřemte jed ).

Nevím, jak to řeší javovští programátoři. Za sebe mohu řict, že to řeším opačně konstruovanou "podestýlkou". Vždy to co je na vrchu, tak to je vidět, tam se pracuje a nejnovější verze pracuje přímo s tím s čím mám. Každé rozhraní předchozí verze pak na sebe nabaluje emulaci, která se snaží v novém rozhraní emulovat to staré. Mohu to dát někam jinam, protože každá tahle vrstva se už nevyvíjí, ve vlastním programu se nevyskytuje a slouží jen k zachování kompatibility. To jen na obhajobu mého způsobu. Nejde o nadstavby, ale spíš o podestýlku emululujících vrstev. Kromě nafukování binárky a udržování kompatibility nemají význam. U binárně kompatibilních knihoven jsou nutností (nemám rád termín "uzavřené", protože binární neznamená "uzavřené"), u těch ostatních je to na diskuzi.

Citace
No, otázka je zda se s tou cenou počítá i do budoucna. Pokud někdo navrhne skříň do níž dám pouze jede hrnek, nebo myslivce, který může mít jen jednoho psa a finito, pak si nejsem tou cenou až tak jist.... Pokud je kód ještě navíc uzavřený, myslím že to může to být v budoucnu velmi drahá záležitost. A určitě sám ze zkušenností víte, že peníze mohou být v takovém případě ještě pořád to nejmenší. Ale - je to asi jen věc pohledu...

Otázkou je, zda na začátku navrhujete skříň, nebo tu skříň z toho uděláte až v průběhu vývoje.

Mmad

Re: Jste zastánci OOP programování?
« Odpověď #107 kdy: 11. 12. 2010, 01:52:15 »
Tech: A pokud by se šlo aspoň částečně do mikrojádra (že, plánované kernely 3.x) s delegováním pomocí několika málo serverů, které by nebyl už takový problém udržovat, tak by se problém sajrajtu v jádru na minimum neomezil? Pak si každý vybere jen potřebné moduly-servery a jádro nemusí tahat moc bloated kódu. Navíc se kompatibilita řeší vůči modulu-serveru a ne jádru. On ten polyformismus z OOP má něco do sebe.
Ostatně celé OOP si představte třeba jako vaření (pro dostatečné množství variací). Pak je to spíš otázka jestli tu rýži udělat jako čínu do papírového talířku nebo ji dát k hovězímu v porcelánu.

JS

Re: Jste zastánci OOP programování?
« Odpověď #108 kdy: 11. 12. 2010, 08:47:14 »
Ondra: Vase odpoved je prave to, co mi neni jasne. Rozumite, mohl bych ve vasi odpovedi nahradit slovo "trida" slovem "funkce", a platilo by to uplne stejne dobre. Takze v cem presne mi ty tridy davaji neco navic, nez funkce? (Jde mi ted o reusability, ja souhlasim s tim, ze tridy jsou obcas - treba v GUI - dobra abstrakce, ale takovych dobrych abstrakci existuji mraky.)

Muzete rict, ze to mate vsechno v jednom baleni. Ale me prijde, ze to v praxi je jen malokdy pravda, ze byste mohl vzit jednu tridu nezavisle na ostatnich, ktera by uz mela vlastnosti, co chcete. Spis budete muset vzit vic trid. Muzete namitnout, ze jich porad bude mene, nez vzit vic funkci a struktur, ale to je dvousecne - zase pokud berete vic trid, zvysujete pravdepodobnost, ze budou obsahovat zatez, kterou nepotrebujete.

Proste, moje pointa je, ze uzitecnost te tridy jakozto abstrakce neni nutne jednotka znovupouzitelnosti. Tedy nevidim, jak to v praxi pomaha znovupouzitelnosti. Ze to neskodi jsem ochoten pripustit (i kdyz mi prakticky prijde, ze tridy jsou jen dalsi misto, kam se daji schovat spagety). Prijde mi, ze to s tou znovupouzitelnosti v OOP si nekdo na zacatku vymyslel jako hypotezu, a pak to po nem vsichni zacali opakovat.

Podle me, vetsina jazyku ma system modulu, a ten resi znovupouzitelnost lepe, nez jestli je jazyk OOP nebo ne. V jednom modulu muzete mit jak vic funkci, tak vic trid, a mate tam presne to, co se tyka dane veci. To jak rozdelite program do modulu nijak neovlivni jeho semantiku, a tim padem je to idealni abstrakce pro znovupouzitelnost (aby ne, proto to tam je).

ondra.novacisko.cz

Re: Jste zastánci OOP programování?
« Odpověď #109 kdy: 11. 12. 2010, 12:23:12 »
JS: Problém u funkcí budete mít s uložením dat. Funkce nejsou stavové narozdíl od objektů. A pokud si k uložení dat uděláte strukturu a sadu funkcí, které stou strukturou pracují a to celé vystavíte jako "modul", pak už vlastně méte objekt a dalo by se říct, že je to na dobré cestě k OOP.

Pořád si tu někdo myslí, že OOP je nějaký programovací jazyk. Není. OOP je programovací technika a ta se dá realizovat i v ne OOP programovacím jazyku. Jazyky označené za OOP mají jen některé vlastnosti, které výrazně zjednodušují tvorbu objektu (za pomocí tříd).

To ne-OOP řešení se většinou vztahuje ke klasickému řešení, kdy program je napsán na míru nějaké existující relační databázi s pevným formátem... pro příklad. Nemůžete vzít libovolnou funkci, z toho projektu aby fungovala samostatně, nutně narazíte na to, že musíte převzít celý datový model.

U OOP řešení ten datový model je sestaven s objektů stejně jako vlastní program, protože objekty si datové modely tahají sebou (třída definuje jak datový model, tak funkce, které s daty pracují a nikdy jiný s daty pracovat nesmí, proto mohou pracovat samostatně).

Samozřejmě, že některé objekty vyžadují jiné objekty a pokud chcete ty objekty použít, musíte v programu použít i ty, na kterých jsou ty původní objekty závislé. Ale naštěstí nemusíte importovat celý původní projekt. Jako že mám zkušenost s projektem, kde nebyla jiná možnost, přestože jsem z původního projektu použil jen zhruba 5% celkové funkcionality.


jk

Re: Jste zastánci OOP programování?
« Odpověď #110 kdy: 11. 12. 2010, 14:40:19 »
@o.n.c
Nesouhlasim s tim, ze je treba prebrat u funkci datovy model. Funkce (a tak to bylo odjakziva) se maji koncipovat tak, ze preberou potrebna data v argumentech a neco s nimi udelaji. Vysledek opet predaji v argumentech nebo v nejakem returncod. Takova funkce vubec nevi, ze nejaky datovy model existuje.

Souhlasim s vami, ze OOP neni programovaci jazyk.
OOP (_prostredi_) pouzivam, protoze mi nic jineho nezbyva. Vpodsatte neexistuje GUI , ktera neni v C++ s vyjimnou gtk , ale tam_me_vadi_ty_nazvy_funkci(ktere_gtk_pouziva). Musel jsem se v roce 2001 tedy rozhodnout, ktery z tech frameworku pouziji (qt, fox, wx, fltk).  A v tomto prostredi mi vadi ta omezeni, ktera jsou zamerena na to, aby programator neslapl vedle. Uvedu priklad prave z toho roku 2001, kdy jsem stal pred problemem:

Program si nacte nejaky textovy predpis, podle ktereho se maji v dialogu rozmistit na souradnicich x,y elementy (button, label, textfield ...) v nejake velikosti. Programove (pro pozdejsi pristup k temto elementum (objektum) ) musi(muze)  tedy existivat nejaky vektor objektu, ktery tyto graficke objekty spravuje.( napr. obj_vektor[]) Kazdy nejaky takovy vyse uvedeny framework ma takovou tridu=Objekt, ze ktere jsou pak ostatni (konkretni butony, labely...) odvozeny. Nejaky konkretni objekt umistim v dialogovem okenku za pomoci metody treba setX(), tedy napr. button umistim button->sexX(20). Co ale nefunguje, je volani metody obj_vektor[5]->setX(20), protoze trida objekt zadnou metodu setX() neimplementuje. Co ted?

ondra.novacisko.cz

Re: Jste zastánci OOP programování?
« Odpověď #111 kdy: 11. 12. 2010, 14:56:19 »
@o.n.c
Nesouhlasim s tim, ze je treba prebrat u funkci datovy model. Funkce (a tak to bylo odjakziva) se maji koncipovat tak, ze preberou potrebna data v argumentech a neco s nimi udelaji. Vysledek opet predaji v argumentech nebo v nejakem returncod. Takova funkce vubec nevi, ze nejaky datovy model existuje.
Valná většina funkcí bude mít v jednom parametru strukturu představujcící stav nějakého objektu, který ta funkce modifikuje. v OOP jazycich je to this. Podivejte se do svych programů a spočítejte, kolik takových funkcí tam máte.

JS

Re: Jste zastánci OOP programování?
« Odpověď #112 kdy: 11. 12. 2010, 17:20:23 »
JS: Problém u funkcí budete mít s uložením dat. Funkce nejsou stavové narozdíl od objektů. A pokud si k uložení dat uděláte strukturu a sadu funkcí, které stou strukturou pracují a to celé vystavíte jako "modul", pak už vlastně méte objekt a dalo by se říct, že je to na dobré cestě k OOP.

No, to prave nemam objekt. Muzu si totiz tech struktur v tom modulu udelat vic, a proto je objekt nanejvys specialnim pripadem modulu. Takze, muzu svou otazku polozit znovu - jak mi OOP pomuze, resp. v cem je to vyhodnejsi pro reusability nez klasicke modularni programovani s funkcemi?

Ale asi to nema smysl. Podle me zadny skutecny dukaz pro vase tvrzeni nemate; jinak byste mi uz takovy poskytl.

P.S. A v jazyce s lexikalnimi uzavery mohou funkce byt stavove (nakonec, uzavery lze vyuzit k vytvoreni objektoveho systemu, nicmene uzavery maji mnohem sirsi rozsah pouziti).

Logik

  • *****
  • 1 049
    • Zobrazit profil
    • E-mail
Re: Jste zastánci OOP programování?
« Odpověď #113 kdy: 12. 12. 2010, 11:22:01 »
Citace
Já mám neblahé tušení, že nevíte co rozhraní je. Zvlášť po tom, co se ptáte, kterého myslivce máte poslat na lov. To je jako kdyby jste se ptal, u televize, která má dva video vstupy, kompozitní a SCART, kterým vstupem připojíte video?
No a já mám zas dojem, že to nevíte Vy. Vy byste opravdu udělal Televize implements IScart?
K tomu není co dodat, jen, že v okažiku, kdy dostanete televizi se dvěma scarty, tak jste... no víte kde. Schválně: hoďte sem příklad kódu televize implementující rozhraní IScart tak, aby podporovala dva Scarty. A aby šla co nejrychleji a s co nejméně modifikacemi rozšířit o další konektor (ať už SCART nebo s novým rozhraním HDMI). Až to uděláte, dam sem své řešení já (už ho mám v hlavě) a můžeme porovnávat.

Citace
U úředníka kontrolujícího psy můžete mít také vlastní rozhraní. Je to rozhraní, kterým komunikuje úředník s myslivcem.
A tomu říkáte reusability? Pro každou blbost vytvořit nové rozhraní? Reusability imho znamená také to, že navrhuji rozhraní tak, aby ho mohli používat pokudmožno všichni. Tzn. když někdo chce vědět, jakého mám psa(y), tak ať už je to veterinář, úředník nebo ras, tak použije to jedno stejné rozhraní.

Citace
Rozhraní není objekt, je to komunikační protokol.
Nesouhlasím, ale o tom jsme si psali. Že to je blbina jde ukázat třeba na TCP/IP. Copak je TCP/IP (komunikační protokol po ethernetu) rozhraním ethernetu? Jedním z největších vynálezů v síťování bylo oddělení vrstev s tím, že vyšší vrstva nezáleží na nižší.
S Vaším přístupem by ale nižší vrstva (ethernet) musí znát všechny protokoly, které po něm poběží.

Já tvrdím, že rozhraní je v podstatě popis objektu, říká čím objekt je (Myslivec) popř. co umí. Takže ethernet umí posílat pakety na danou MAC, tak bude mít metodu pošli paket. Jaký komunikační protokol nad tím vystavím je ethernetu naprosto šumák - to neni jeho věc.

Citace
A pak jsem pochopil, že Vás trápí název rozhraní. Ale název je jen idenitifikace a nemusí mít
význam...
No, mě trápí to, že rozhraní Myslivec ve skutečnosti nepopisuje myslivce, ale jeho velmi speciální případ. Takže není znovupoužitelný, protože málokdy budu potřebovat takový speciální případ myslivce.
Podtrhuje to i to, že navrhujete, ať ho tedy nepojmenuju myslivec, ale AASDSDSDS. Samozřejmě, v jednom programu bych takový název zkousnul. Ale vy byste takové rozhraní použil v jiném projektu?
Jméno jako takové je pouze identifikátor. Ale jedním z programátorských pravidel je: Co mohu jednoduše popsat tak, že každý dle názvu pozná, o co jde, je správně napsané. A čím jednodušeji to jde popsat, tím je to napsané lépe. (A pokud možno, název objektu/rozhraní by měl shrnovat tento popis do jednoho "multiSlova" popř. "multi_slova" - pak je v podstatě půl dokumentace hotové).

V podstatě to znamená, že čím se mi podaří problém rozložit na jednoduší samostatné entity, tím bývá design programu lepší (samozřejmě s mírou). A ještě významnější důsledek: čím jsou tyto entity obecnější, tím je design programu lepší.
I proto je myslivec je lépe napsaný než myslivec s jedním psem a rozhodně mnohem lépe než myslivec co chodí k úředníkovi, myslivec, co chodí k veterináři atd...

Citace
Občas se stane, že během vývoje rozhraní svůj název přestane dokonale vyplňovat.
Pokud se toto stane, pak je IMHO chyba v designu. Pokud mám rozhraní IMyslivecSePsem a najednou potřebuji myslivce s více psy a rozhraní předělám, neodpovídá název. A o čem to svědčí? Že při analýze jsem chybně myslel, že stačí jeden pes.
Dokonce bych řekl, že to bývá jedna z velmi častých chyb při programování - pokud rozhraní A nevyhovuje, protože na daném místě vlastně očekávám B, tak místo abych nadefinoval B a použil ho, ohnu A. Pak o pár dní později zjistím, že jsem ohnul A a tak mi nevyhovuje zas tady, a tak se ho snažím ohnout zpátky - a vznikne paskvil.

Pozor, to je jiný případ než s myslivcem: myslivec s jedním psem i s více psy je furt myslivec, tady nejde o ohnutí, ale opravu. Pokud ale někde chci příjmat smečku a v současné době tam příjmám psa, je velká chyba (byť někdy z důvodu nemožnosti modifikace zbytku kódu nejmenší zlo) ohnout rozhraní Pes. Správné řešení je nadefinovat nové rozhraní Smečka.
« Poslední změna: 12. 12. 2010, 11:36:40 od Logik »

ondra.novacisko.cz

Re: Jste zastánci OOP programování?
« Odpověď #114 kdy: 12. 12. 2010, 21:35:43 »
No a já mám zas dojem, že to nevíte Vy. Vy byste opravdu udělal Televize implements IScart?

Jak to s tím souvisí? Copak televize musí implementovat rozhraní pomocí implements? Jistě může, ale nemusí. Rozhraní přece neříká, jak má být implementováno. Jen předepisuje, co má být implementováno. To "jak" patří do zodpovědnosti toho, kdo to implementuje

K tomu není co dodat, jen, že v okažiku, kdy dostanete televizi se dvěma scarty, tak jste... no víte kde. Schválně: hoďte sem příklad kódu televize implementující rozhraní IScart tak,
aby podporovala dva Scarty. A aby šla co nejrychleji a s co nejméně modifikacemi rozšířit o

I kdyby měla televize implementova deset SCARTů, pořád budete muset nadefinovat rozhraní jednoho SCARTa. Pořád budete potřebovat IScart

další konektor (ať už SCART nebo s novým rozhraním HDMI). Až to uděláte, dam sem své řešení já (už ho mám v hlavě) a můžeme porovnávat.

Hele, tohle jsem už nedávno řešil. Mám model, který má rozhraní, kterým model ovládám a ten model své výstupy posílá na rozhraní, které sleduje jeho view. Mám to rozhraní implementovat jako jedno, nebo jako kontejner?  No já vím, že budu jednou potřebovat model prohlížet z vícero než z jednoho pohledu. Ale patří tohle vůbec do zodpovědnosti modelu? Já jsem to vyřešil pomocí distributoru, objekt, který slouží k rozdělení jednoho rozhraní do mnoha rozhraní. Z jedné strany se napojí na model a k druhému se připojují ta view. To je asi odpověď na Vaši otázku. Ano, ta krabice co máte na stole umí 2 SCARTy. Ale já se na televizi mohu podívat jako na objekt, který podporuje jedno rozhraní a to pomocí Implements. A před něj strčím objekt multiplexeru, kterým to budu přepínat a který zvládne těch rozhraní více klasicky funkcí getRozhraní(int index). Mám pak větší volnost. Mohu přímo televizi připojit ke zdroji, bez toho abych tam rval proxy objekty (což přesně dělá Java, kdy implementace jedné metody se deleguje na další metodu, další metodu, další metodu a někde v desáté úrovni je vlastní kód) a nebo prostřednictvím multiplexu vyrobím televizi s vícero rozhraními a celé to pak mohu zabalit do jendoho velkého objektu TelevizeSViceScarty.

Co je asi nejdůležitější, té černé krabičce na druhé straně rozhraní je naprosto šumák, jakým způsobem je to rozhraní implementováno. Jestli tam je televize připojena přímo přes implements, nebo přes proxy objekty, nebo jakkoliv jinak. Třeba tam ani televize být nemusí. Proto pořád tvrdím, že NEVÍTE co to slovo ROZHRANÍ znamená. Roz-hraní. Anglický termín inter-face je výstižnější... mezi-ksicht. Doslova definuje protokol mezi dvěma ksichty. A název toho rozhraní by mělo vystihovat co možná nejpřesnějí smysl protokolu.

Citace
A tomu říkáte reusability? Pro každou blbost vytvořit nové rozhraní? Reusability imho znamená také to, že navrhuji rozhraní tak, aby ho mohli používat pokudmožno všichni. Tzn. když někdo chce vědět, jakého mám psa(y), tak ať už je to veterinář, úředník nebo ras, tak použije to jedno stejné rozhraní.

Bohužel, každého bude zajímat něco jiného. Zatímco veterinář se asi bude ptát na jeho zdravotní historii, úředníka bude zajímat třeba úplně něco jiného. Nemůžete při návrhu mýchat deset věcí do jednoho. re-usabilita není v tom, že to namatlám do jednoho zdrojáku a ten použiju všude. re-usabilita je v tom, že si jednotlivé cihly rozeberu a použiju třeba samostatně. Třeba v systému, kde mám jen psy a veterináře nemusím mít myslivce a úředníky. Proč bych měl tedy do takové aplikace tahat třídy nebo rozhraní Myslivec a Úředník.

Citace
Citace
Rozhraní není objekt, je to komunikační protokol.
Nesouhlasím, ale o tom jsme si psali. Že to je blbina jde ukázat třeba na TCP/IP. Copak je TCP/IP (komunikační protokol po ethernetu) rozhraním ethernetu? Jedním z největších vynálezů v síťování bylo oddělení vrstev s tím, že vyšší vrstva nezáleží na nižší.
S Vaším přístupem by ale nižší vrstva (ethernet) musí znát všechny protokoly, které po něm poběží.
Nevíte co je to rozhraní! Jak jste přišel na to, že nižší vrstva musí znát všechny protokoly nad ním?

Citace
Já tvrdím, že rozhraní je v podstatě popis objektu, říká čím objekt je (Myslivec) popř. co
Rozhraní v programovacím jazyce Java nebo C++ definuje, jaké metody můžete nad objektem spouštět s jakými parametry a jaké návratové hodnoty ty metody vrací. Nevidím tam nic o popisu objektu. Nejsou tam stavové proměnné, které objekt maximálně vystihují. Neříkají nic, co ty metody mají ve skutečnosti dělat, což bych si jako popis objektu nejvíc představoval. Když rozhraní IPes má metodu štěkej() neznamená to, že objekt na druhé straně zaštěká. Pokud místo psa vezmu vyhledávacího robota, který při štěkání bude blikat žárovkou, tak zabliká. Pokud bude tenhle pes sloužit k účelu, ke kterému druhá strana rozhraní IPes používá, nevidím na tom nic špatného. Když diskovému ovladači pošlu příkaz na zápis dat, neznamená to, že data se zapíší na disk. Klidně se mohou poslat po síti. Nebo se mohou vypsat na obrazovce. Smyslem rozhraní je to, že jedna strana neví o té druhé nic, ale v jedom má jistotu. To že rozhraní nějakým způsobem implementuje. Rozhraní však neříká jak.


Citace
Citace
Občas se stane, že během vývoje rozhraní svůj název přestane dokonale vyplňovat.
Pokud se toto stane, pak je IMHO chyba v designu. Pokud mám rozhraní IMyslivecSePsem a najednou potřebuji myslivce s více psy a rozhraní předělám, neodpovídá název. A o čem to svědčí? Že při analýze jsem chybně myslel, že stačí jeden pes.

Nesvědčí to o ničem. Třeba o tom, že z projektu za pár korun, který měl 200 řádek se stala korporátní aplikace s 200 tisíci řádky a to co autor projektu na začátku předpokládál už dávno neplatí. Sám vidíte, že nemohu ani rozhraní předělat. No jasně, je čas pro nové rozhraní!

A o tom jestli dále budete emulovat staré rozhraní musíte rozhodnout podle toho, jaké náklady a přínosy vám emulace nebo neemulace přinese

Pamatujete si na WinAmp 3? To byl mrtvej projekt, protože s vydáním WinAmpa se změnila všechna rozhraní, a nenechala se ta stará. Kde udělali soudruzi chybu?
a) Nepředpokládali při vývoji WinAmp 1, že bude existovat WinAmp 3?
b) Rozšířili stará rozhraní o nové funkce?
c) Nezachovali stará rozhraní v původním návrhu.

Já tvrdím, že c). Vy mě přesvědčujete, že a) je správně

ondra.novacisko.cz

Re: Jste zastánci OOP programování?
« Odpověď #115 kdy: 12. 12. 2010, 21:48:56 »
Ještě k těm rozhraní a implements.

Mám tady teďka něco jako rozbalený RPC protokol do jednotlivých nodů. Mám tady NumberNode, StringNode, BoolNode, ArrayNode, atd... Všechno to jsou třídy, které uchovávají hodnoty načtené z RPC protokolu nebo to umí zase uložit v tomtéž formátu. No a já jsem se teď rozhodl, že v jednom projektu bych potřeboval všechny tyhle třídy obohatit o tyto metody:

Kód: [Vybrat]
String toString();
String getStringValue();
void setValue(String value);

V zásadě, první metoda převede obsah každého objektu na nějaký řetězec, který se dá vypsat. Druhá metoda převede pouze hodnotu na řetězec, třeba proto, aby se dala vrazit do editačního políčka pro editaci. Třetí metoda vezme řetězec, rozparsuje ho a nastaví objekt do nové hodnoty podle obsahu toho řetězce. Takže pokud u NumberNode tam dám 1, nastaví se do hodnoty 1. U BoolNode tam budu moci poslat "true" nebo "false".  Pokud to nepůjde převést, vyhodí to výjimku.

A teď zadání, mám takovou knihovnu plnou takovýhle nodů. Už je někde napsaná, používá se a bude používat na mnoha místech. Jak to udělat, aby každá tato třída měla tyto tři metody.

a) upravím původní rozhraní a obohatím ho o nové funkce?
b) napíšu to jako nové rozhraní.
c) jsem blbej, nepočítal jsem při vývoji software s takovou variantou. Mohlo mě přece napadnout, že jednou budu chtít strukturu upravovat uživatelem

Co je správně? Poraďte mi, ať to vyřeším.

Logik

  • *****
  • 1 049
    • Zobrazit profil
    • E-mail
Re: Jste zastánci OOP programování?
« Odpověď #116 kdy: 13. 12. 2010, 16:48:46 »
Ad IScart: Takže to chápu tak, že to uděláte jako

Kód: [Vybrat]
Televize -<Iskart>- Multiplexor  -<Iskart>
                                 -<Iskart>
                                 -<Iskart>

A jak pak třeba uděláte volbu, který kanál na televizi pustit? To bude řešit ten multiplexor? A když budete chtí přidat HDMI, tak předpokládám musíte měnit definici multiplexoru? Nebo pro každé rozhraní bude mít televize vlastní multiplexor - takže budu muset měnit i samotnou televizi?

Citace
A před něj strčím objekt multiplexeru, kterým to budu přepínat a který zvládne těch rozhraní více klasicky funkcí getRozhraní(int index). Mám pak větší volnost.
Ne, IMHO máte zaděláno na chybu. Je večer, koukáte se na nejnovější epizodu seriálu přes settopbox. Přijde malej klučina, kterej neví nic o tom, že televize má více scartů (tedy že tam je ještě multiplexor) a vezme scart od videa a zapojí ho do televize do volného konektoru (použije rozhraní IScart od ITelevize). No a co udělá televize? Začne mixovat data z multiplexoru s daty ze scartu. Nebo přepne rovnou na to video. ale to by reálná televize neudělala.

Tím, že implementujete rozhraní IScart jak u televize, tak i u multiplexoru prostě není jasné, co se má kam připojovat - tímto řešením jste vytvořil zbytečný zmatek.

----

Já bych to řešil takto: Mám televizi. Ta má nějaké konektory. Z těch tečou do televize různá data, takže interpretace těch dat je v podstatě záležitost "konektorů" (každej má jiné). No, a když jsem to takhle popsal, tak už je návrh jasný:
Kód: [Vybrat]
ITelevize {
public:
   IKonektor getKonektor(typKonektoru, pozice=0)
   //metody pro komunikaci s konektorem
   void prijmiVideoData(IKonektor, data)
   void prijmiAudioData(IKonektor, data)
}

IKonektor {
    bool zapocniPrijem() //konektor začne posílat data televizi
}

IHMDIKonektor extends IKonektor
{
    void prijmiPaket();     
}

IDsubKonektor extends IKonektor
 {
    void prijmiRGB();     
}
 
IScartKonektor extends IKonektor
 {
     void prijmiRGB();     
     void prijmiKompozit();     
    void prijmiAudio();     
 }
nevím, jestli to co teče DSubem je totéž, co teče skatem, pokud jo, pak by ještě mělo být rozhraní IRGBKonektor, z kterého by se podědil jak scart, tak RGB.

No a výhody: pro vytvoření televize s jiným rozhraním nemusím vůbec šahat do televize. Pouze vytvořím a implementuji nové rozhraní pro nový konektor (display port). Do televize musím šahat pouze, pokud televize má umět něco více. Pak ale v podstatě to už není ta stará televize, ale např. televize s teletextem, takže v tu chvíli není nic divného na tom, že musím tu televizi upravit (a pravděpodobně podědit nové rozhraní).

Mohu vytvořit televizi s jedním, třemi scarty,sedmi scarty a vždy bude jasné, co kam zapojit a televize se furt bude chovat tak jak má.

A celý tento podle mne čistý návrh plyne z toho, že se na rozhraní koukám nikoli na komunikační protokol: to bych opravdu měl televizi přiřadit rozhraní IScart, protože telvize s ním komunikuje, ale jako na entity. Takže pokud má televize scart konektor, tak prostě telvize musí poskytnout patřičný objekt, nikoli rozhraní. Z toho vyplývá mé chápání rozdílu mezi třídou a rozhraním: rozhraní říká CO, třída říká JAK.

---

Citace
Bohužel, každého bude zajímat něco jiného.
Ne vždy. A spousta informací bude společných. On už koncept myslivce je zbytečně speciální - správný koncept je IMHO např. vlastník zvířat. Ten poskytuje metody jako jaká mám zvířata apod. Pokud veterinář chce něco speciálního, tak pak vytvořím pro něj nové rozhraní: protože člověk, co k němu chodí je speciální případ člověka, neboť umí speciální dovednost: podat veterináři informace o zdravotním stavu zvířat. Stejnětak člověk cestující přes hranice např, musí umět dát doklady.
Koncept myslivce v podstatě pak zahrnuje těchto x různých schopností. Máte pravdu v tom, že v jedné aplikaci může být potřeba posílat myslivce k veterináři, v jiném nikoli. V tu chvíli opravdu v každém může být pro "myslivce" (naschvál v uvozovkách, protože každý myslivec vlastně označuje něco jiného) jiné rozhraní. To je ale rozdíl proti tomu, když mám v jednom projektu myslivce s jedním psem a v druhém myslivce s více psy. Myslivec s více psy evidentně zahrnuje i myslivce s jedním psem. Ale nemohu vzít myslivce s jedním psem a přidat mu vlastnictví více psů - protože furt ten myslivec bude mít jednoho "privilegovaného" psa navíc.
Mohu samozřejmě jeho metody přepsat tak, aby toho psa navíc integroval do smečky - jenže to mě ve výsledku zabere více práce, než kdybych vzal myslivce bez psa a implementovat v něm metody vlastnictví psů.

Citace
Jak jste přišel na to, že nižší vrstva musí znát všechny protokoly nad ním?
Vy tvrdíte, že rozhraní je komunikační protokol, pomocí které daná entita komunikuje s ostatními objekty. Např. switch v ethernetu příjmá data v protokolu TCP/IP (a posílá je dálú Ergo kladívko, měl by implementovat protokol TCP/IP. To je důsledek vaší definice rozhraní - jako komunikační kanál.

Já tvrdím, že implementovat rozhraní znamená být/mít schopnost. Switch nemá schopnost rozumět protokolu TPC/IP, proto nemá toto rozhraní implementovat.

---

Ad název rozhraní. Doporučil bych Vám připustit, že někdo může mít jiný názor a že jedním slovem (např. rozhraní) může každý označovat trochu jiný pojem. A že pokud ten pojem není pevně přiřazen ke slovu (což v OOP není, jinak by nebyly ty sáhodlouhé debaty, který jazyk je ten jediný správně OOP), že se nedá říci, který význam daného slova je správnější. Takže se prosím smiřte s tím, že chápu pojem rozhraní trochu jinak než vy a místo hádek o termíny se pojďte bavit o tom, který z těch významů je praktičtější a proč.

Co se týče psa a štěkání, tak IMHO slučujete dvě věci. Jedno je schopnost přijmout povel ke štěknutí (k zápisu na disk, k ....). Tomu odpovídá dané rozhraní IStekable s meodou štěkni. Druhá věc je pes ten je zpravidla štěkable, proto by měl implementovat dané rozhraní.
Pak mohu vymyslet koncept psa: řeknu, že pes (rozhraní IPes) je zvíře (extends IZvire), které umí štěkat (extends IStekable). Kodkoli teď může vyrobit (implementovat psa) a může mi ho poslat a já budu vědět, co s ním.

No a pak jsou dvě věci. Někdo umí ovládat psy. Takový člověk by nikdy neřek štěkej robotovy, on to umí se psy. Takže komunikuje s rozhraním IPes. Tento koncept je ale užitečný spíše zřídka. Anebo někdo umí dávat povely ke štěkání: pak umí s rozhraním IŠtěkable a je mu jedno, komu ty povely posílá.... a co protistrana dělá.

Váš pojem rozhraní je pak v podstatě specializace mého: schopnost rozumět konkrétnímu protokolu je vlastnost a jako taková může mít své rozhraní. Až na to, že tím, že si přesněji specifikuji, co je rozhraní, vyloučím špatné návrhy. Např. u televize:
Televize rozumí protokolu scartu? No to přece až tak ne: když scart pustím do HDMI, tak tomu nebude rozumět. Ten kdo rozumí protokolu scartu je pouze ten konektor televize.
A mám s minimem námahy (IMHO hodně dobrý) návrh.

Zatímco ve vašem přístupu televize opravdu komunikuje scartem, takže není nic divného na tom, aby toto rohraní implementovala - v tu chvíli se ale dostáváte do problémů a musíte vymýšlet nějaký multiplexor a stejně to nemusí fungovat - kdokoli může narvat signál do televize přímo.

---
Na zbytek už nebudu reagovat, protože už jsem asi desetkrát psal, že mluvím o tom, jak by se měli aplikace navrhovat od začátku a že pokud je návrh na začátku blbej, tak přepsat ho na dobrej je sice akademicky čisté, ale ne vždy možné či nejlevnější řešení.
 

ondra.novacisko.cz

Re: Jste zastánci OOP programování?
« Odpověď #117 kdy: 13. 12. 2010, 20:01:56 »
Na zbytek už nebudu reagovat, protože už jsem asi desetkrát psal, že mluvím o tom, jak by se měli aplikace navrhovat od začátku a že pokud je návrh na začátku blbej, tak přepsat ho na dobrej je sice akademicky čisté, ale ne vždy možné či nejlevnější řešení.

Vida, a zrovna to nejzajímavější jste vynechal. A mě zrovna zajímal váš názor na problém který řeším s tím RPC (NumberNode, StringNode,...) Teda já řešení znám, ale zajímá mne Váš názor.

Protože zatímco všechny příklady tady byly akademické, tak můj poslední příspěvek se opírá o reálnou situaci. Klidně Vám pak dám odkaz do repozitáře, kde najdete řešení, abych dokázal, že nekecám.

Logik

  • *****
  • 1 049
    • Zobrazit profil
    • E-mail
Re: Jste zastánci OOP programování?
« Odpověď #118 kdy: 14. 12. 2010, 14:47:40 »
Na to "nejzajímavější" jsem nereagoval, protože za a) o tom jsem od začátku nic netvrdil (debata začala od čistýho návrhu nějakejch rozhraní do RPG, nikoli o jejich úpravě, toto téma do debaty furt zavlékláte vy), zadruhé je to natolik závislé na tom, jaký je to projekt, kolik lidí a jakým způsobem se podílí na vývoji, jak velk jsou potřeba úpravy a čeho všeho se úpravy dotknou atd...., že nelze říci, kterou metodu bych zvolil. Pro pořádek v kódu je vždy nejlepší mít rozhraní čistá, ale člověk musí často dělat kompromisy.

Jinak to StringNode etc... jsem vynechal proto, protože se na to zaprve vztahuje celý předchozí odstavec, zadruhé jsem se chtěl věnovat tomu, co je IMHO důležité a to mi stačilo demonstrovat na televizi, a za třetí jde o rozšíření funkčnosti, naprosto nezávislé na původním účelu objektů (serializovat/deserializovat do/z řetězce můžu i naprosto cokoli a je mi jedno, jestli to je node nebo islámský terorista) tak není důvod, proč pro to nezavést nové rozhraní (nebo ještě lépe použít již existující rozhraní na serializaci), naopak by byla chyba toto rozhraní vázat na nějaké nody. (Navíc by ta rozhraní i mohla být dvě, protože jedna věc je serializace do strojového zápisu a druhá věc serializace do human-readable, ale to je detail).
S původním tématem to tedy nemá v podstatě společného už vůbec nic.
« Poslední změna: 14. 12. 2010, 14:49:36 od Logik »

ondra.novacisko.cz

Re: Jste zastánci OOP programování?
« Odpověď #119 kdy: 14. 12. 2010, 15:36:37 »
Na to "nejzajímavější" jsem nereagoval, protože za a) o tom jsem od začátku nic netvrdil (debata začala od čistýho návrhu nějakejch rozhraní do RPG, nikoli o jejich úpravě, toto
téma do debaty furt zavlékláte vy), zadruhé je to natolik závislé na tom, jaký je to projekt,

Nevím, kdo mě tu přesvědčoval o tom, že když od začátku píšu skříň, že musím už dopředu počítat s tím, že do ní vložím víc než jeden šálek. Nevím, kdo psal o tom, že v OOP musím při změně rozhraní měnit všechny objekty, které rozhraní používají (načež jsem argumentoval, že vždycky můžeme vytvořit rozhraní nové, namísto změny toho stávajícího). Celá diskuze se točí o udržení čistého kódu po celou dlouhou dobu vývoje software, nikoliv o jednorázovém návrhu. Vy akorát vždycky celou debatu stočíte k tomu, že jde jen o čistotu počátečního návrhu hlavně proto, že byste musel přiznat, že mám celou dobu pravdu. O čemž jsem se přesvědčil právě ve Vaší poslední odpovědi ke které jsem Vás donutil

původním účelu objektů (serializovat/deserializovat do/z řetězce můžu i naprosto cokoli a je mi jedno, jestli to je node nebo islámský terorista) tak není důvod, proč pro to nezavést nové rozhraní (nebo ještě lépe použít již existující rozhraní na serializaci), naopak by byla

Předně tak a o tom to celé je. Mám objektovou strukturu, která už funguje a potřebuju jí nějakým způsobem rozšířit, aniž bych zasáhl do původních rozhraní. Vždycky mohu vytvořit rozhraní nové a nové objekty, které budou dědit původní objekty a nové rozhraní. A funkce nového rozhraní implementovat. Konečně Javovský canvas taky nemá ve svém základním rozhraní funkce pro práci s myší. Musíte to podědit a implementovat rozhraní MouseListener. Zajímavé je také, že MouseListener nemá nic společného s Canvasem, přestože vy jste mě celou dobu přesvědčoval, že IMyslivec, konstruované pro lovecký účel by měl implementovat víc psů,i přesto že jsem k lovu doposud potřeboval jen jednoho. MouseListener přitom slouží k zachytávání akcí myši (IMyslivec slouží k zachytávání informací o revíru během lovu nebo výkonu myslivosti) a nemá sloužit k ničemu jinému (IMyslivec není vhodný k návštěvě veterináře).

Taky jsem psal, abyste se nenechal zmást názvem, protože jistě, mohl jsem to nazvat ne IMyslivec, ale IMyslivecNaHonuListener. Hypotetický autor aplikace pro hony a výkon myslivosti se však domníval, že rozhraní by se mělo jmenovat IMyslivec, protože je pravděpodobné, že na hon budou chodit hlavně myslivci, i když to nevylučuje účast hostů, kteří sice myslivci nejsou, ale pro účel honu mohou IMyslivec implementovat také.

A jinak nedáváte pozor. Knihovna kterou popisuju je přímo serializační nástroj, nejde o to, že ji chci serializovat, naopak mi šlo o analýzu serializovatných dat, nebo o možnost editovat serializovaná data bez nutnosti mít k dispozici původní aplikaci, která data vytvořila. Ale to je vedlejší, nepřečetl jste si ani zadání (byl tam příkaz vypisující obsah nodu pro zobrazení, pro editaci a pro modifikaci), hned mi cpete něco, co jsem vlastně ani nechtel.