Problém OOP vidím spíš v tom, že ho nikdo pořádně neumí. A i když už ví vo co go, tak ho neumí správně a efektivně použít. Tím neříkám, že třeba já jsem výjimka.
OOP neberu jako dogma, jen jako forma pohledu. Objektově jsem programovál v době, kdy jsem OOP neznal. Jen jsem si to neuvědomoval. Tíhnul jsem k vytváření instancí, černých soběstačných krabiček, které lze snadno instanciovat. Samostatně fungujících jednotek, které standardním způsobem komunikují s okolím a imitují vztahy mezi lidma.
Příchodem lambda funkcí zejména v javascriptu ale i v C++ je to opět posunuto trochu jinam... jenže... ona taková funkce může být chápána jako objekt. Nezřdka kdy přepisuju funkce na rozhraní, protože prostě jedna funkce je málo na nějaký obecnější vyjádření. Jindy zase přizpůsobuju objekty, aby dobře pracovaly jak s objektem, tak s funkcí. V javascriptu může mít funkce vnitřní stav.
function create_counter(start) {
var cnt = start;
return function() {return cnt++;}
}
var counter = create_counter(10);
console.log(counter());
console.log(counter());
console.log(counter());
Je to funkce nebo objekt?
Pokud tento objekt voláním přijme message, aby vrátil jako výsledek jinou message, je to objekt. Je to jen úhel pohledu.
Totálne si to nepochopil. Nekritizuje to bunka A posle data bunke B ale kritizuje cely ten nezmysel čo je v Jave. Tvoj priklad je navyše nezmyselný, lebo ani nevieš čo je a čo neni OOP, porovnavaš OOP s OOP a na jedno OOP nadavas zatial co druhe vyzdvihujes, ale pri tom je to ten isty OOP. Až bys vyskúšal Golang, Ruby, ERLang a pod. a psal bys neOOP, pochopil by si jak moc je OOP v podobe javy nezmyselné, už to kolik design patternov potřebuješ vedieť abys to OOP samotne docielil svedčí o tom že celú prácu to komplikuje.
Tys to nepochopil. Ne bez patternov to nejde, pokiaľ sa jedná čo i len o trocha komplexnejší projekt. Když sa pokúšaš o to to psať bez patternov, pak to vyzerá tak že všade sa len kód "hackuje" a "ohýba" a když máš projekt s 20 tisíc riadkami kódu s 80 triedami, s 500 metodami, tak jedna metóda ovplivní funkčnosť polovice tried, metód a kódu. Chceš osoliť hranolky a odpáliš nukleárnu bombu. Kdyby to šlo bez design patternov, proč by boli vôbec vymyslené?
23. 7. 2019, 13:17 editováno autorem komentáře
myslíte counter? No to byl příklad. Ale já takle mám dělané streamy.
function parse(stream) {... whatever....}
function create_string_stream(string) {
var s = string;
var l = string.length;
var i = 0;
return function() {
if (i >= l) return null; else return s.charAt(i++);
}
}
$ var s = create_string_stream("hello world")
undefined
$ s()
"h"
$ s()
"e"
$ s()
"l"
$ s()
"l"
$ s()
"o"
$ s()
" "
$ s()
"w"
$ s()
"o"
$ s()
"r"
$ s()
"l"
$ s()
"d"
$ s()
null
$ s()
null
Zkuste si v prohlížeči. Parser samozřejmě očekává funkci co vrací další znak dokud není konec streamu. Mam plnou svobodu mu jako zdroj znaků poskytnout cokoliv.
Jinak používám javascript k vyjádření algoritmu. Všechny tyhle postupy používám v C++. Ale to si asi těžko vyzkoušíte
U class bych musel vymýšlet rozhraní. musel bych pak dědit ten class - moc komplikovaný
takhle mohu napsat
parse(function() {
//...
return ...
})
a vyšvihnout tam inline generátor. Jde o to, že rozhraní je jasně daný. Je to funkce, volá se bez parametrů a vrací další znak. string_stream je jen jedna možná implementace. Čtení ze souboru bude vypadat jinak ale bude mít stejně jednoduché rozhraní.
Zápis do streamu je zase funkce, která přijímá znak. Případně null (zapíše EOF)
Funkce nemůže mít „vnitřní stav“, funkce může mít jen kontext, to je tento případ.
V případě, že bychom připustili, že counter je objekt s jedinou metodou, jejíž desktiptor se tudíž při posílání zprávy neuvádí, tak by to OOP sice připomínalo, ale OOP to vlastně není, protože klíčovou vlastností je, že objekt může přijmout JAKOUKOLIV zprávu a zpracovat ji. To zde neplatí.
Kdyby return vracel dictionary funkcí, pak by bylo možno uvedením názvu jednotlivé spouštět, ale opět by to nebylo OOP, protože situaci, kdy se odkážeme na neexistující položku dictionary, nevede na zachycení neznámého deskriptoru metody a vyřešení situace „objektem“.
Závěr: Tohle OOP není.
Asi jsem totálně mimo. Funkce že nemůže mít vnitřní stav? A co tedy vidíte?
Ale jo, rozumím tomu, že "správně zadefinovaná" funkce nesmí mít vnitřní stav. Ale běžně píšu funkce a potažno lambda funkce, který běžný vnitřní stav mají. Je to OOP programování nebo funkcionální programování?
vemte si objekt. Objekt příjme zprávu, a zpracuje ji, eventuálně generuje další zprávy na jíne objekty.
function vytvor_objekt(params) {
var vnitrni_stav = params;
return function(zprava) {
switch (zprava.nazev) {
case "get" : return vnitrni_stav;
case "set" : vnitrni_stav = zprava.hodnota;return;
default: return "neumim";
}
}
}
$ var obj = vytvor_objekt(10)
undefined
$ obj({nazev:"get"})
10
$ obj({nazev:"set", hodnota:20})
undefined
$ obj({nazev:"get"})
20
$obj({nazev:"aaa"})
"neumim"
Je to funkce nebo objekt? Přijímá to zprávy, zapouzdřuje to vnitřní stav, dědičnost by se dala udělat dekompozicí (prostě by potomek do vnitřního stavu zahrnul předka a neznámé zprávy by forwardoval předkovi) a to by řešilo i polymorfismus.
Pořád ne? Musíte mít na to úředně razítko, nebo umíte změnit úhel pohledu? O tom to totiž je
Je to uzávěr, ne funkce s vnitřním stavem (interně nějaká struktura s funkcí a ukazatelem na její okolí, což mimochodem komplikuje vůbec základní způsob práce s těmito strukturami).
Jinak to myslíš a píšeš dobře, jen nepoužíváš správnou terminologii a lidi se na to chytají (a mají taky pravdu).
Nechme ale mluvit klasika nejklasičtějšího:
The venerable master Qc Na was walking with his student, Anton. Hoping to
prompt the master into a discussion, Anton said "Master, I have heard that
objects are a very good thing - is this true?" Qc Na looked pityingly at
his student and replied, "Foolish pupil - objects are merely a poor man's
closures."
Chastised, Anton took his leave from his master and returned to his cell,
intent on studying closures. He carefully read the entire "Lambda: The
Ultimate..." series of papers and its cousins, and implemented a small
Scheme interpreter with a closure-based object system. He learned much, and
looked forward to informing his master of his progress.
On his next walk with Qc Na, Anton attempted to impress his master by
saying "Master, I have diligently studied the matter, and now understand
that objects are truly a poor man's closures." Qc Na responded by hitting
Anton with his stick, saying "When will you learn? Closures are a poor man's
object." At that moment, Anton became enlightened.
Bude to stačit takto?
https://stackoverflow.com/questions/2497801/closures-are-poor-mans-objects-and-vice-versa-what-does-this-mean
popř. v kontextu JavaScriptu: http://skilldrick.co.uk/2011/09/closures-vs-objects-fight/
Zkráceně: jedno není náhrada druhého (ani naopak). Jedná se spíše o dva přístupy, které sice mají společný průnik, ale spíše se doplňují, než aby se všude používaly buď uzávěry nebo naopak všude objekty (nezávisle na tom, zda class-based nebo prototype-based).
Nikdy by mě nenapadlo srovnávat uzávěry a objekty jenom proto, že v každém je kdesi jakýsi stav, asi proto jsem to nepochopil. Že jde uzávěra olemplovat objektem, bych pochopil, ale jak jde zasílání zpráv objektu olemplovat uzávěrami, to nechápu.
Každopádně děkuji za odkaz, kde nejúspěšnější vysvětlení začíná větou „Consider Java.“.
Psal jsem, že objekty a uzávěry jsou 2 různé věci, které se sotva můžou vzájemně nahrazovat!
Jsou to dva ruzne koncepty, ktere se v praxi bezne nahrazuji.
Z jedne strany v Jave jsou lambda vyrazy a s nima spojene uzavery reseny pomoci objektu.
Z opacne strany neni problem nad uzavery postavit objektovy system, bezne se to pouziva pri vyuce programovani vychazejici z Lispu/Scheme. Objekt lze udelat jako variadickou funkci, ktera jako prvni argument bere zpravu a funguje jako dispatch, ktera preda argumenty dal prislusne metode. Kdyz se to hezky obali makry, vypada to, jako by to v tom jazyce bylo odjakziva.
„...Objekt lze udelat jako variadickou funkci, ktera jako prvni argument bere zpravu a funguje jako dispatch, ktera preda argumenty dal prislusne metode...“
Tohle je první funkční řešení objektu uzávěrami, co jsem tu viděl.
Tohle teoreticky funguje, z praktického hlediska je nevýhodou, jestliže každý objekt obsahuje svoje vlastní instance funkcí, protože to často zabírá více místa než stavy, což se při např. desetitisících objektů projeví. Asi by se daly „dispatchované“ funkce vyčlenit do něčeho jako prototyp či třída a odkazovat je na kontext jednotlivých objektů...
Po letech praxe mohu zodpovědně prohlásit, že největší kritici OOP pocházejí z tábora lidí, co nemají o objektovém programování valného povědomí, případně jsou totální chaotici.
No a taky není od věci si vybírat k určité práci ten správný nástroj. Kleštěmi sice hřebík zatluču, ale kladívko bude lepší, že...
22. 7. 2019, 21:40 editováno autorem komentáře
Amen.
Standardni blabol haskelloveho jehovisty.
Nejprve sestavim sadu strawmanu, otresne blbych architektonickych examplu a tuto hloupost svedu na OOP paradigma.
Pak pridam starou dobrou ignoranci, zmatlam dohromady class level encapsulaci a application business stav, problem je samozrejme v OOP, protoze architekt byl tak pitomy, ze neslysel ani o MVC a roztahal business stav aplikace po ruznych tridach, jak ho napadlo.
Je zbytecne to dale rozmazavat, pregnantne to vyjadril ve sve reakci Vlad Balin:
https://medium.com/@gaperton/let-me-start-from-the-less-obvious-thing-7f49e87a45ca
Z pohledu zadavatelů není důležité hodnocení, jestli je neschopný programátor, technologie či styl programování. Důležitý je výsledek v průměrném případě. OOP, když se umí, je asi lepší. Podmína "když se umí" je v praxi těžce dosažitelná.
Myslím, že 90 % hamburgerů připravených doma na grilu překoná McDonald's. Domácí gril je OOP. McD ale potřebuje miliony zaměstnanců po celém světě, kteří dokáží splácat žemli s karbanátkem během tří minut, s minimem odpadu a s přesně stanoveným množstvím ingrediencí. To je procedurálníá programování. Umožňuje dopřát si mírně nadprůměrný burger za rozumnou cenu a s minimálním rizikem excesů (zapomenuté suroviny, moc omáček apod.).
Z mého pohledu: OOP má mnohem vyšší vstupní práh pro programátora. Odvádí pozornost od algoritmizace k sémantice. Rychlé zásahy v kódu jsou složité, protože je potřeba nastudovat široké okolí. Špatně navržený objekt je nečitelný a jeho refaktorování zabere hodně času.
Dobrým příkladem procedurálního programování by mohlo být jádro Linuxu. Neobjektovost nic neubírá ani na jeho čitelnosti a rozšiřitelnosti.
„Z mého pohledu: OOP má mnohem vyšší vstupní práh pro programátora.“
Dle zkušeností Smalltalkařů pouze u procedurálních/strukturovaných programátorů (to je bohužel většina, což vysvětluje tento názor; taky jsem to zažil), u lidí nezasažených těmito myšlenkovými konstrukcemi NAOPAK nižší.
„Rychlé zásahy v kódu jsou složité, protože je potřeba nastudovat široké okolí.“
Je to PŘESNĚ NAOPAK - je-li objekt uzavřenou jednotkou s definovaým rozhraním a funkcionalitou, není třeba znalosti jeho vnitřku, naopak to bývá kontraproduktivní.
„Špatně navržený objekt je nečitelný a jeho refaktorování zabere hodně času.“
To přece platí o každém kódu. Nedodržuje-li objektový návrh princip odpovědnosti a související stavy i logika překračují hranice objektů, dostáváte se na úroveň procedurálního programování.
Dobre je srovnat si kod napr. v OpenBSD a OS/X, to je znacny extrem. Musim rict, ze ty objektove veci OS/X temer nejsem schopen pochopit (trva to strasne dlouho a clovek jen zasne co se tam deje), kdezto kod OpenBSD staci jen prolitnout a je hned jasno.
Nicmene neni to asi jen o OOP: Kod System V ci V7 Unixu src/uts je pomerne ciste C, ale nektere casti (mm, alokator) jsou i tak naprosto necitelne. Nebo veci ve Windows, ty jsou nektere navrzeny tak slozite (asi postupem casu jak to dobastlovali), ze i pres ciste C a po precteni dokumentace nejsem schopen s jistotou rici jak se neco bude chovat.
Ja teraz obcasne pozeram zdrojove kody isteho RTOS, ktory je pisany v osekanom C89 a je to zatial asi najnecitatelnejsi kus kodu, ktory som kedy videl hned po zdrojakoch MS-DOSu 6, ktory bol pisany v assembleri. Codebase tej veci ani nie ze zavratne velka, radovo maximalne niekolko MB.
Predtym som pracoval na projekte napisanom v C++11, ktory mal radovo miliony riadkov zdrojovych kodov a bolo to pomerne slusne citatelne. Clovek si sice obcas preskakal cez viacero tried kym zistil, co je kde v typovom systeme implementovane, ale kod samotny sa cital a chapal celkom dobre (vzhladom k velkosti codebase).
OOP/neOOP naozaj na inherentnu citatelnost kodu nema vplyv. To ako si ho niektore jazyky urobia ale mat moze. Kazdopadne najvacsi vplyv na to ma indent style a stabna kultura programatorov.
Koukám, že letos ta okurková dorazila později.
Tak nějak si vybavuju asi bambilionšest článků/ukřivděných blogů/... na téma "oop je největší zlo".
Jako fain, ale proč to "dokazovat" na jazyku/implementaci/whatever, o které(m) se ví, že to tam bylo taknějak naroubováno?
PS: Mají čtverec, kružnice a verlyba společnýho předka?
PPS: A posílají si zprávy, nebo volají funkce/metody?
(post edit: omlouvám se, ale první verze odešla podivně zmršená)
Pokud ty (virtuální) metody budou různé, v objektovém jazyce stejně budete muse napsat každou zvlášť. A napsat si v C univerzální wrapper, který pro kteroukoli z těch struktur zavolá její vlastní close() handler, je triviální.
Schválně se zkuste podívat na to, jak se v jádře pracuje třeba právě s těmi sockety ( struct sock -- struct inet_sock -- struct inet_connection_sock -- struct tcp_sock). Zjístíte, že dědičnost a polymorfismus nejsou zase až tak unikátním výdobytkem objektových jazyků, jak jste si možná myslel.
A ked pridam dalsi druh socketu cez nejaku kniznicu tak si musim napisat override na ten 'univerzalny' wrapper aby dokazal zavolat close() aj nad tou novou kniznicou namiesto toho aby proste kniznica zdedila zo socketu a implementovala svoj close() a ja nemusim nic pisat len stale zavolam xxx.close(). Netvrdim ze sa to neda len nevidim tu vyhodu pre ktoru by som to mal robit inac ako objektovo.
Ono je nakonec z praktického hlediska úplně jedno, jestli tomu říkáte virtuální metody nebo tabulka callbacků/handlerů. V praxi je to totéž a funguje to stejně, rozdíl je jen v té troše pohodlí. Samozřejmě i v tom, že objektový jazyk od vás odstíní, jak to ve skutečnosti funguje - ale tam už je diskutabilní, zda je to výhoda nebo nevýhodap; zajímalo by mne třeba, kolik programátorů v objektových jazycích si uvědomuje, jak moc jsou závislí na indirect callech a co pro ně prakticky znamená zavedení retpolines kvůli Spectre.
Netvrdil jsem, že je to výhodnější a když budu psát projekt v C++, tak samozřejmě použiju virtuální metody a ne strukturu s callbacky. Chtěl jsem jen upozornit, že objektový jazyk a jeho nástroje nejsou vůbec nutné pro techniky jako dědičnost a polymorfismus, protože to jde třeba i v C - a dokonce se to běžně dělá.
Kdybych měl schrnout článek čtyřmi citacemi autora:
"What are the other options? Is your organization already is using C#? Give F# a try "
Jablka jsou lepší než hrušky! Celou dobu tvrdě obhajuje použití funkcionálního programování místo OOP. Protože funkcionální programování má přece základ v lambda kalkulu, kdežto OOP ne.
"I expect some sort of reaction from the defenders of OOP. They will say that this article is full of inaccuracies. Some might even start calling names. They might even call me a “junior” developer with no real-world OOP experience. Some might say that my assumptions are erroneous, and examples are useless. Whatever."
Bohužel, článek skutečně obsahuje nepřesnosti, a kdyby autor měl trochu víc praxe, pochopil by, že nekritizuje koncepty OOP, ale špatné použití těch konceptů.
"Does the piece of paper you’re writing on have a “write” method? No! "
"We’ve been told that global state is the root of all evil. It should be avoided at all costs. What we have never been told is that encapsulation, in fact, is glorified global state."
22. 7. 2019, 22:26 editováno autorem komentáře
Ten článek se tváří jako dobře sestavená kritika OOP, ale hned od počátku se dopouští tolika dogmatických a nepodložených tvrzení, neustále si odporuje, že nemá smysl to jednotlivě rozebírat. Těžko můžu přijmout argumentaci postavenou na tom, že se jedna věc shazuje a druhá nekriticky obdivuje jakožto svatý grál programování.
Zkrátka autor (ač s mnoha lety praxe) nepochopil, že OOP, FP a jakékoli další koncepty jsou jen různými projevy téhož a jsou to jen nástroje u kterých je vždy na programátorovi, jak a kde je použije (či zneužije).
Autor má pravdu, že Java je otřesně navržená a s Kayovým OOP nemá mnoho společného. Dost ale pochybuju, že spásou je zrovna funkcionální programování. V OO jazyce může funkční (byť většinou blbě navržený) kód spáchat i průměrný lepič (jichž je většina), kdežto v FP jsou intelektuální nároky podstatně vyšší. Proto se ostatně FP mimo akademickou sféru moc nerozšířilo.
Spásou je Golang, 2 roky prace v ňom a totalne ti zmení myslenie, a to tak v akomkoľvek projekte v akomkoľvek štádiu budeš vedieť skočiť medzi ostatnych typkov čo to programovali, a do 5 sekund vieš čo to robí, jak je kód psaný, a hneď vieš nadviazať, a sám efektivne napíšeš za chvíľu tucet novej funkcionality do softwaru. V Jave nemožné, ani kdyby ten projekt byl napsaný sebevíc dokonale. V Jave máš furt obavu že když zmeníš jeden riadok kódu v metóde ktorá pečie zemiaky, že to spôsobí že ti už nenastartuje auto.... Najhoršie je polimorfizmus, Inheritence, dokopy vytvára závislosti všetkého na všetkom. Presný opak toho čo by malo byť cieľom pôvodného OOP.
v Golangu jsem bohuzel delal pul roku a snad uz nikdy vice.
Z nejake priciny nekdo zamerne odignoroval 20 let vyvoje CS a udelal cosi z roku 1980 s pridanyma gorutinama, coz je jedina pekna zalezitost golangu a s pridanym garbage collectorem.
Neumi to vyjimky a jeste to prezentujou jako znouzectnost.
Kod je pak plny bordelu typu
x,err=func(blabla)
if(err) {
defer handler()
}
y,err2 = func2(bleble)
if(err2) {
handler(2)
}
V libovolnem jazyce s vyjimkama mam jasne oddeleny blok business funkce a error handlingu.
V tom hnoji ukazanem vyse mam z celkem 8 radku kodu 2 radky tykajici se business logiky, 3/4 je balastni hnuj.
A kdyz chci prohledat error handling, musim si najit ty handlery, nekde na druhem konci zdrojaku... Nebo to strcim inline primo do defer function{} - pak mam pomer business logika/balast tak 1:10...
Hnus, porad musim procitat hromady balastniho hnoje a pracne preparovat business logiku/error handling.
Nebo neexistence generik. Vzdyt golang nema ani takovou trivialitu jako je sorted map. V C++ od pocatku veku.
Ale chapu, ze pro cloveka, co srandovne jednoduchou Jawu poklada za slozity jazyk, je Golang dobry.
Zaklad golangu obsahne gibbon za odpoledne, kdyz to nic neumi, neni toho moc se ucit.
Tady je ale problém trochu jiný. C++ dlouho nemělo unordered_map ve standardní knihovně. Ale nestandardních hashmap bylo k dispozici celkem dost, protože se přes templaty dala implementovat bez jakékoliv změny v samotném jazyce. V Go máš prostě smůlu.
C++ je složité mimo jiné protože je to obecný jazyk pro hromadu různorodých věcí. Go je doménově specifický jazyk navržený přesně na problémy, které řeší Google.
píšeš jeden príklad, kde to je najviac problémové, ostatne ale "try-catch" zabere 4 riadky taky. I v jave mohu napsať:
try {
// funkcionalita
}
catch (Expection e) {
// handle error
}
a vidíš, 6 riadkov, a len jeden je funkcionalita.
ak si odpustíš catch, tak to je to isté ako napsať podtržítko v e promennej. Navyše pri komplexnejších kódoch naopak u Javy sa nabalí balastu omnoho viac. A Java určite neni srandovne jednoduchy jazyk, keby bol, nemuselo by byť vymyslené stovky design patternov, aby sa nestávali situácie že zmením kód v stroji na obrábanie zemiakov, a ono to rozbije atomovú elektráreň.
A proc bych mel proboha kazde volani metody balit do separatniho try-catch bloku?
V Jawe muj go priklad vypada takto
try {
x = obj.method1();
y= obj.method1();
} catch (Exception e) {
..handle
}
Abych vedel, co dela business logika, stavi precist 2 radky volani metod uvnitr try.
Abych vedel co dela handler - staci precist obsah v catch bloku.
V GO je debilne zmatlana business logika s error handlingem, navic jeste v pripade defer funkci si musim i analyzovat poradi vkladani na defer zasobnik.
Defacto, abych pochopil business logiku, musim dekodovat kompletni kod vcetne error handlingu. Kontrolovat si, jestli tam nekdo nezavolal defer, co se spusti uplne mimo flow pri opousteni funkce.
V Jawe vidim proste zavolani 2 metod po sobe - to je vse.
V catch bloku je kompletne lokalni handling.
Nebe a dudy.
A netusim co to tu melse o zemiakach a atomovych elektrarnach.
Java ma naopak mnohem vymakanejsi ochranu proti nechtenemu zasahu do objektu zvenci (public, private, protected, package specific, final)
Go ma jenom primitivni public/private rozliseni pres uppercase prvni pismeno funkce.
Design patterny jsou prosty popis best practices jak resit bezne problemy, netusim co to ma mit spolecneho s kvalitou jazyka.
Bezne GoF paterrny jsou v Golangu nepouzitelne, protoze to je jazyk tak nemohouci, ze tyto implementovat nelze.
Golang design patterny jsou samozrejme standard, tady mas popis pipeline patternu:
https://blog.golang.org/pipelines
Vyuziva kanaly a gorutiny, coz je jedina pekna vec na golangu. Jinak je go zoufalstvi.
A? To chces "usetrit" tim, ze odstranis to handlovani?
Kazdopadne zrovna tenhle pripad je krasne citelny a primocary. Urcite vic, nez ten bordel v golangu.
(A jde to samozrejme i jinak, pri osetreni chyb muzes uz nejaky cas v Java pouzit i postupy inspirovane FP. V tom golangu mas smulu a nemuzes pouzit prakticky nic.)
Sice ne zrovna dlouho (v poměru k věku), ale Java dneska má spoustu užitečných věcí jako Optional, lambdy a streamy. Také moc pěkný executor mechanizmus, až ho Python zkopíroval [1]. Jo, `go moje_metoda()` je kratší než `Executor.submit(moje_metoda)`, ale ve výsledku to dělá skoro to samé.
[1] https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.Executor
Golang naopak nemá nic z těch dobrých vlastností ostatních.. generika, čitelný error handling.
A dynamické struktury jsou v Golang peklo. Zkuste si přistupovat k pod.spec.template.spec.metadata.annotations.neco, když tam může cokoliv z toho chybět. V Javě s Optional nebo v Pythonu alespoň s výjimkami je to triviální a čitelné.
Totálně možná změnilo myšlení tobě, ale když se na Go podívám já, tak to takhle nevidím. Nemám nic proti jednoduchým jazykům a Go jde v této linii, ale žádné nové a zajímavé paradigma nepřidává, nic mi v hlavě nového nedocvaklo. Když to porovnám třeba s konkatenativními jazyky, Lisp a ML jazyky, "pure" OO (Eiffel, Smalltalk), prototypovými (Self) a dokonce i C++ (šablony). Třeba Python je fajn a dělám v něm skoro vše, ale že bych ho takhle adoroval, to už mám za sebou. S Pythonem je to jen sňatek z rozumu. V Javě jsem taky něco napsal -- tenkrát jsem byl blázen do DDD (a stále jsem) a věř mi, že i po letech se ten "dobře nadyzajnovanej" kód refaktoruje a mění líp než co jsem psal v Pythonu, což je nejen kvůli dostupným nástrojům, ale i jazykem samotným. Java není tak špatná a Go není spása.
23. 7. 2019, 10:38 editováno autorem komentáře
Na dědičnosti není nic špatného, když je nepovinná (např. ve Smalltalku, Pythonu, ...). To ale neplatí u Jávky (a dalších s*aček), protože tam se kýženého polymorfismu nedosahuje zasíláním zpráv, ale voláním podtypově příbuzných (tento hovadismus se zove „podtypový polymorfismus“), čímž se dědičnost stává povinnou, takže zabřednete buďto do vymýšlení správné hierarchie, nebo (u vícenásobné dědičnosti) do bordelu mezi předky. Nebo do smršti rozhraní.
Nadměrné používání dědičnosti považuju za selhání výuky programování. Z praxe vidím, že je to celkem okrajová featura, většina tříd nepotřebuje být v nějaké hierarchii.
Ohledně "smršti rozhraní" - interface je prostě způsob, jak automaticky ověřit, že objekty dostávají zprávy, které očekávají. V některých jazycích to musí hlídat sám programátor, v některých to (alespoň částečně) ověří překladač. Obojí má své místo pod sluncem. Pokud tam je těch rozhraní hodně, tak to svědčí o špatném návrhu, jazyk nic takového nevynucuje.
Ehm?
O interfacech jsi uz nejspis slysel. Proc je teda dedicnost v Jave povinna?
Hlava mi to prilis nebere, osobne jsem jsem nepsal dedenou tridu ani nepamatuju, na vsecko pouzivam interfaces.
A vicenasobna dedicnost a bordel mezi predky v Jave?
Pan bude zrejme znalec.
V mem vesmiru Java vicenasobnou dedicnost nepodporuje.
V mem vesmiru se pouziva dedeni pro pripady, kdy chci rozsirovat funkcionalitu pri zachovani stavajicic.
Typicky HashMap -> LinkedHashMap
Pro proty polymofrni pristup k objektum se pouzvaji vetsinou intrefaces.
Rozhraní jsem zmínil, takže ano, pak platí, že k dosažení polymorfismu je třeba buďto dědičnosti nebo rozhraní. Ve Smalltalku a Pythonu ani jednoho, a o to tu šlo.
Měl jsem na mysli např. C++, napsal jsem to špatně.
V mém vesmíru se používá dědičnost všude tam, kde je to výhodné ke sdílení kódu. V mém vesmíru se také používá diakritika, aniž by k tomu bylo třeba velkého znalectví.
Ta smršť rozhraní je i v tom Golangu. Jediný rozdíl je v tom, že v Javě je musíte uvádět. Ta implicitní rozhraní v Golangu jsou opravdu docela fajn, ale Java také nespí a má od v. 8 rozumný počet dobře definovaných rozhraní pro funkcionální přístup - https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html
V tom Golangu pak také není všechno růžové. Java sice vyžaduje uvádět typy i pro výjimky, zatímco Golang má obecný error. Jenže zjistit z hlavičky jaké errory může funkce v Golang vrátit je nemožné (a z kódu skoro - někdy to bublá pěkně z hluboka).
Spíš FP dobře funguje na "čistých" problémech. V praxi jsou ale problémy skoro vždy "chlupaté", mají různé výjimky "když tohle" a "když tamhleto". Ne, že by se to FP nedalo řešit, ale už to zdaleka není tak elegantní. "Čisté" problémy tak řeší hlavně akademici. Aneb "mám řešení, ale funguje jen pro sférickou slepice ve vakuu" :-)
Filosofické letní téma :)
No, přechroupal jsem to, a přijde mi že autor trochu brečí na špatném hrobě. Ty věci co OOP vytýká jsou sice validní, aneb zprasit se dá leccos a lecjak. 10+ levelů dědičnosti kde na levelu 3 přidáte funkci SetX() a na levelu 7 SetXPos() kde obě nastavují různým způsobem pozici X, ale vzájemně se někdy ruší ale někdy ne... OO to je, ale P to není.
Funkcionální programování je zatím na TODO listu k nastudování takže nemůžu kritizovat moc fundovaně, ale když se kouknu na příklady uvedené autorem, mám strach aby to jeho "funkcionální programování" nevypadalo jako v kódech z mé první práce (plain C, 1000ln+ dlouhé funkce, proměnné abcd1234, parametry funkci definovane multi-level makry které probíral menší lesík #ifdefů... ).
Nebo lépe, řetězec 30 nesrozumitelnych lambd kde jedna volá druhou... Asi mi pak bouchne mozek až budu přemýšlet co v té současné capture je a není, proč to autor napsal tak jak to napsal, proč to zrovna v té 27. lambdě hází segfault/vyjímku, a hlavně, proč se mi to zase GDB zaseklo při rozbalování callstacku když ho zrovna potřebuju. :D
Už to že dvaja programatori čo si zastávajú OOP, a neOOP programatori OOP nepochopili, pričom když sa dvaja takýto stretnú tak obaja svoje "OOP myslenie" podávajú v úplne inej forme, a sami sa nedohodnú, už to jasne dokazuje, jak je OOP v podobe Javy nezmyselné. Pre každého ten pojem jaksi niečo iné znamená. A když sa nedá pevne definovať význam OOP v Jave, tak je zrejmé že je to preto lebo ani sama Java jakožto jazyk netuší čo zač je, nechápe sama seba, taký je to chaos.
Je zajímavé jak si autor příspěvku myslí něco o OOP a nezkusil si Smalltalk. Zmiňuje se o něm velmi okrajově, ale neváhá citovat Alan(a) Kay(e) o OOP (sice hlavně o Javě, ale přeci).
Co bych autorovi doporučil? Vyzkoušet si Smalltalk a nastudovat si trochu jeho historii, je dost krvavá, že by vydala i na román (napříkald to, že první Java VMky dělali prakticky výhradně Ti co dělali VMky pro Smalltalk)
Zde je co by mohl udělat:
1) Podívat se na svět OOP očima Smalltalku
2) Kouknout se na důvody proč se Smalltalk ne prosadil (nápověda: technologií to opravdu není)
3) Vyhlédnout si implementaci Smalltalk VA Smalltalk (pohrobek IBM Smalltalku/V, vyspělá, ale drahá - komerčně nasazená), Smalltalk/X-jv branch (velmi schopná implementace o kterou pečuje Jan Vraný, která je prakticky neznámá a je zadarmo, lze zkompilovat ze zdrjových kódů - komerčně nasazená), a poslední pro použití v reálném životě je objektová databáze je GemStone/S (asi v současnosti nejvyspělejší smalltalk) - s DB do 10GB zdarma.
Dále jsou tu menší projekty jako:
GNU Smallltalk, Dolphin Smalltalk (Smalltalk pro Windows) kdysi placený smalltalk, dnes open source, Squeak - zajímavá na hraní, ale nevím co do použití pro reálný projekt, Amber - Smalltalk běžící na/v Javascriptu.
Schválně jsem vynechal dvě implementace, které v současnosti mají velké problémy a tou je VisualWorks od Cincomu (odkud odešla naprostá většina vývojářů) a tou druhou je Pharo, které je sice open source, ale je to více méně akademický projekty a má velké problémy se stabilitou a vývojem VM.
4) Neskloňovat pořád jen Alan(a) Kay(e) ale podívat se hlouběji a najít si neméně či možná více zajímavé osobnosti jako je například - Ward Cunningham.
OOP má jiný zásadní problém. A to ten, že už vlastně vůbec nikdo neví, co to to OOP vůbec je.
Porovnejte si OOP v Smalltalku, Selfu, Javě, C++, Javascriptu a Lue a řekněte mi, co tam je společného. Všechno je to OOP, jenom to pokaždé znamená něco jiného. A v tomhle prostředí se jakákoliv kritika strašně jednoduše shazuje. Prostě tomu kritik nerozumí a vlastně vůbec neprogramuje objektově. :)
Z původní myšlenky už zůstal jen cool název. A asi proto se teď pro objekty v původním Kayově významu používá spíš termín "mikroslužby". A pod starým názvem se skrývají minimálně tři vzájemně nekompatibilní přístupy.
A tohle jsou podmínky nutné, nebo postačující? IMO ani jedno.
- Třeba Lua nebo Javascript vlastně žádné zapouzdření nemají.
- Takové Go dědičnost nemá vůbec a ve spoustě klasických dynamických jazyků (jako třeba smalltalk) je dědičnost jen syntaktický cukříček nad přeposíláním zpráv "někam" dál.
- Polymorfismu je spousta druhů. S konceptem objektů se AFAIK pojí ten podtypový. A třeba v C++ se běžně pracuje s objekty, které polymorfní nejsou.
- A abstrakci jsem si nechal nakonec. Tu jsem zatím v žádné definici OOP nepotkal. Asi proto, že v našem oboru je abstrakce úplně všechno.
A nic, jen že Pavel ukázal, že mnoho lidí dneska si pod pojmem OOP představuje něco jiného, než je Kayovo OOP, což i v této diskuzi vede k problémům, protože si každej představuje něco odlišného (prostě je to tvárný termín, který kdysi zneužilo pár firem a konsorcií).
O tom, že dnešní class-based OOP se subtypovým polymorfismem přesahují původní Kayovu myšlenku, se tady bavit moc nebudu - protože to IMHO není pravda, spíš se naopak oklikou vracíme k původnímu konceptu objektů a asynchronních zpráv (ale ne v mainstreamových jazycích).
Mluvíš úplně o něčem jiném. Celou dobu tu řešíme, co si běžný programátor představí pod pojmem OOP. Zkus si udělat anketu a uvidíš, že 95% lidí si představí právě "Encapsulation, Abstraction, Inheritance, Polymorphism.
To, že se dá objektově programovat i když to jazyk nepodporuje je pravda, ale proč bych si to proboha dělal? To, že jsou jazyky, kde si pod OOP představují něco jiného je taky pravda. Ale běžné použití toho pojmu znamená tohle.
Co se snažím říct je, že tyhle věci bývají spojené s pojmem OOP ale vlastně opačným směrem. Tři z těch čtyř věcí nejsou něco co OOP definume, ale něco co se dá udělat i pomocí OOP. Z významu těch pojmů se to, co to oop vlastně je, odhadnout moc nedá. Běžný programátor si pod pojmem OOP představí classy z Javy případně podobnou věc z jeho jazyka. Prostě nějaké balíčky dat a kódu pohromadě. Zapouzdření a podobně jsou abstraktní pojmy, které chápe právě skrz to jak je to zapsané v jeho (objektovém) jazyce.
Jinými slovy. Pokud uděláš anketu tak možná 95% lidí odpoví to samé. Ale budou tím myslet různé věci určené tím, jaký jazyk budou mít na mysli. Něco jiného si představí Javista a něco jiného webař i když z nich třeba vypadne stejný abstraktní pojem.
jojo takto to odhrká, protože se to bralo v nějakém předmětu na VŠ. Ale co si pod těmi pojmy _představí_? Skutečně těch 95% lidí dokáže říct, co to znamená polymorfismus a kde se může uplatnit? To dost pochybuji, IMHO dají dohromady subtypový polymorfismus.
A "abstrakce"? To znamená "skrývání komplexnosti", což dělá už assembler (vysokoúrovňový strojový ḱód), céčko, vlastne cokoli nad strojákem.
No já se na školeních setkal, že v tom je dost hokej. Něco jiného tvrdí Javisti, protože jsou ovlivněni class-based OOP Javy s rozhraními. Něco trošku jiného lidi od C++ a otázka je, co si myslet o JavaScriptu a Pythonu. Podle mě to jsou OOP jazyky, i když například "encapsulation" se tam dělá dost přes ruku. Na druhou stranu Object Pascal má u tříd dokonce pět typů přístupu: public, private, strictly private, protected, published - znamená to, že má vlastnost "encapsulation" implementovanou na vyšší úrovni, nebo je "encapsulation" pouze obecnější (tvárnější) koncept?
A možná bráno do důsledků - je jakýkoli jazyk umožňující přístup k atributům objektů vůbec objektový ve smyslu, že podporuje "encapsulation" (původní OOP s něčím takovým explicitně vůbec nepočítá, protože se veškerá komunikace s objektem odehrává pomocí zpráv).
Taky jsou zmatky ohledně polymorfismu, kde lidi okolo Javy a C++ často dávají rovnítko polymorfismus==subtypový polymorfismus (a přiznám se, že na pohovorech se ptáme právě na toto a jen málokdo to dále rozvine). Jenže ten pojem je obecnější.
Takže termín OOP je bohužel tvárný
Tady žádný velký prostor pro relativizaci NENÍ. Kdo OOP vymyslel, se ví, jak to myslel, se taky ví. Tak co tady pořád řešíte? Za to, že soudruzi z Javy nepojmenovali svůj experiment „rádobyOOP ve stylu Javy“, původní OOP nemůže, to je jejich blbost. Že se začnu nazývat prezidentem Rakouska, ještě neznamená, že jím opravdu jsem.
Bohužel tady ten prostor je. S pojmem OOP nepřišel jako první Smalltalk ale Simula. A už tady se to začíná větvit. C++ a následně pak Java, nebo C# vycházejí přímo ze Simuly. Simula ještě nedotáhla oop do čisté podoby, to až právě ten Smalltalk. Ale to Javoidní OOP se stihlo odvětvit ještě před tím. Ten prostor tu máme už od počátku. A samozřejmě že se to větví dál.
V té hybridní/statické větvi (vycházející přímo ze Simuly) se od sebe třeba C++ a Java dost vzdalují. Už bych se bál tvrdit, že Java je zjednodušené C++.
A v té čisté/dynamické větvi ze Smalltalku se to zase větví na třídy vs. prototypy a podobně.
Takže sorry, ale o žádném původním versus rádoby OOP nemůže být řeč. Mohli bychom se leda tak dohadovat jestli se tomu původnímu Simulovskému OOP podobá spíš ta Java nebo Smalltalk. Ale do toho vážně nejdu.
Simula měla sice první třídy, ale předpokládám, že fungovaly pouze jako structy (tj. ono javoidní pseudoOO), nikde se mi nepodařilo dohledat, že by to používalo jakékoliv zasílání zpráv či dispatching na straně objektu. Pokud vím, tak se tomu ani OO neříkalo, ten termín neexistoval, byl použit teprve později Kayem pro objekty se zasíláním zpráv.
Kayovo OO mechanismus vzniku objektu neřeší.
Zatím mi připadá, že "vo tom to je". Každý trochu rozsáhlý software se musí s těmito čtyřmi živly sblížit - a je vcelku jedno, jestli ho píšete v Javě, C++, holém C nebo assembleru. Prostě k tomu vede potřeba zvládat složitost. Tohle láteření na OOP (vs. procedurální přístup)... vždyť je to celé blbost. Nebo je možná blbost, označit linuxový kernel jako procedurálně napsaný software...
Osobně láteřím především tím směrem, že software je čím dál složitější, a to z několika důvodů:
1) umí toho čím dál víc
2) modeluje čím dál složitější realitu
3) možná se občas nevyhneme over-engineeringu
4) rozvratné spodní proudy jako příliš detailní modelování "business procesů", které by stálo za to především zbavit zbytečných kliček a kudrdlinek, které jsou dány spíše tradicí a setrvačností společnosti než reálným opodstatněním
5) zadání pro tvorbu a rozvoj softwaru vznikají na základě obchodně-politických tlaků a "pravdu má zákazník", možná někdy ke své škodě?
6) neustálý technický pokrok je hrozná svině
Za nic z toho OOP nemůže. Je jedno v čem ten software napíšete, vždycky vyjde složitý.
„...že už vlastně vůbec nikdo neví, co to to OOP vůbec je.“
Ale h. Termín „object oriented“ vymyslel Kay, sám to řekl, a nikdo mu to nerozporoval, naopak je to považováno za skutečnost, takže z tohoto můžeme klidně vyjít, aniž bychom se museli dohadovat.
Ve svých rozhovorech zmiňuje 2 klíčové vlastnosti, které musí OOP splňovat:
1. zasílání zpráv (toto je zcela klíčové!)
2. zapouzdření
To je celé. Identita objektu pak vyplývá z logiky věci, polymorfismus je důsledkem zpráv, ne dodanou funkcionalitou, ještě se někdy uvádí skládání objektů. Dědičnost se zde NEVYSKYTUJE, přestože 90 % dotazovaných ji uvádí jako klíčový prvek OOP, takže je vidět, jaká představa o OOP panuje a odkud se asi tak vzala.
To je odpověď. Jako test si můžete ověřit, který z vámi vyjmenovaných jazyků je „object oriented“.
No ano. Pokud to budu brát podle Kaye, tak drtivá většina dnešních objektových jazyků vůbec objektová není. A naopak jeho typu objektů se dnes často říká spíš mikroslužby.
Dnes si IMO pod OOP většina programátorů představí spíš jakési balení dat a kódu do jedné entity. A podle druhu jazyka to má pak dost odlišné vlastnosti.
OOP rozhodně není jediný pojem, který skončil takhle znásilněný.
Chce se psat list.inset(item) nebo list_insert(list, item)? OOP je jen syntakticky cukr. I Linus pise objektove, jen si oblibul zapis cislo dva. Z nejakeho duvodu pak vznikly jazyky, ktere si to vynucuji a vynucuji si nejen OOP, ale treba i indentaci. Takove jazyky nemam rad a dost dobre nechapu, ze se tak rozsirily.
Tak asi dělají to co je potřeba aniž by to muselo odpovídat knižním definicím ideálu nějakého konceptu ... jako třeba dřívější js, prostě se tím pomocí několika fukncí ve tvaru modulů oživil web a bylo hotovo, viz. např. jQuery, koho zajímalo co si o tom myslí akademická komise?
23. 7. 2019, 12:58 editováno autorem komentáře
Teraz ste uplne presne trafil. STRUCT a CLASS maju k sebe velmi blizko. Iba v tom CLASS mam 'this' context, mam preciznejsiu moznost volby pristupnosti fieldov (public, private, ...) a funkcie sa mi nepovaluju niekde v sklade dalsich 1000 funkcii ale mam ich tam pekne pokope. Neviem si predstavit ze by niekto extrahoval vsetky funkcie java runtime bez dalsich kniznic ako by som tam hladal to co prave potrebujem.
No a potom su tam dalsie koncepty ktore su uz pre niekoho absolutne neuchopitelne ako dedicnost a polyformizmus a ... co su iba dalsie nastroje v tvojom toolboxe ktore pri spravnom pouziti prinasaju vyhody.
Problém je, že "OOP fanoušci" si vůbec neuvědomují, že nástroje, které jim jejich "paradigma" nebo jazyk poskytují, jsou k dispozici i jinde a často možná i v lepší podobě:
1. Organizace funkcí do jednoho "kontaineru" - moduly, namespacy
2. Zapouzdření dat - opět moduly s exportem konstruktorů, ale bez přímého přístupu k datům pro funkce mimo modul
3. Polymorfismus naprosto není výsadou OOP, v FP apod. typově bohatých jazycích je to triviální
4. Dědičnost je dost sporná (vzpomínám si na zdejší diskusi, zda čtverec je potomek obdélníka nebo naopak), ale pokud jde o sdílení implementace, v jiných jazycích se používají třeba traity.
Takže ano, nástroje - OOP jako nástroj, FP jako nástroj, procedurální programovací techniky jako nástroj - jasně. Ale donedávna se OOP používalo jako dogma a všelék, přičemž jeho konkrétní implementace často přináší spoustu problémů a hází programátorům klacky pod nohy namísto pomoci.
23. 7. 2019, 14:04 editováno autorem komentáře
Ale problem je ze ja a mnoho ludi a firiem je s objektovym programovanim spokojnych a stastnych. Dokazu na tom vytvorit funkcne riesenia ktore drzia svet nad vodou. Neviem preco sa teraz snazi niekto prist a kopat do toho ze je to zle. Piste si v LISPe mne je to jedno. Potom pridte a ukazte nam ako ste to super napisali, bolo treba iba 1/3 kodu a zerie to iba 1/2 RAM a 2/3 procesora oproti rieseniu v Jave. OK. Dovtedy je to iba stekanie psov, karavana MUSI ist dalej.
Myslím, že v dnešní době představitelem hardcore FP není Lisp, ale spíš třeba ten Haskell. "Problémy", které vedou ke kritice OOP jsou jiné:
1. Jak jsem se snažil ukázat, výhody, které OOP nabízejí, neplynou nutně z objektovosti, ale objekty jsou jednou z možností, jak jich dosáhnout. Objektová slepota, kterou způsobilo protežování OOP paradigmatu v posledních dvou desetiletích, zabraňuje dalšímu vzdělávání lidí v oboru.
2. OOP přináší i nevýhody, spousta věcí se dá mnohem elegantněji realizovat pomocí technik vycházejících z FP.
Budoucnost je "postobjektová", "postprocedurální" a "postfunkcionální", i ta vaše Java už je dávno hybridní, zavádí lambdy atd. Za kritiku buď rád, pomáhá všem. Vůbec nemám nic proti používání Smalltalku objektovými nadšenci a Haskellu FP nadšenci, ale bylo by dobré, kdyby znali dobře i jiná paradigmata a věděli, oč svou volbou přicházejí. Většina z nás ale bude používat jazyky, které nejsou takto explicitně vyhraněné a tudíž ten rozhled a nadhled je nutný k tomu, abychom využili současné hybridní programovací nástroje naplno.
Takze sa zhodneme ze napriklad v Jave mam organizaciu kodu so striktnymi datovymi typmi, objektami, mozem robit jednoducho refactoring, nastroje my pomahaju doplnanim kodu ... . Vnutri metody mozem pouzit FP cez streams a closures.
Popri tom mam k dispozicii milion kniznic na riesenie veci ako persistencia objektov do DB, Inversion of Control frameworky, messaging, rule engine, standardne workflow nastroje (BPMN), Aspect Oriented Programming, ... . Takze preco mam akoze prechadzat na ten Hashell? Co by mi to malo priniest? Je kod lahsie citatelny? Je rychlejsi? Zozeniem lahsie programatorov? Ved na programovanie v JVM bezne pouzivam JS na dynamicke casti, rozne template engine (velocity, mustache, ...), BPML, ... ved ja poznam aj FP ale bohuzial nenasiel som na nom zatial ziadnu vyhodu preco by som si to mal tahat do projektov? Dokonca na nom vidim velke mnozstvo nevyhod a rizik ktore iba cakaju na objavenia. FP a jeho frameworky su v infatilnom stave v ktorom bola Java tak 15 rokov dozadu.
Dědičnost a polymorfismus v linuxovém kernelu? I tyhle věci, základní kameny C++, se v Cčku dají aproximovat (a v kernelu se to používá) - spousta structů, které obsahují téměř jenom pointery na funkce. Takový struct je pro mě abstraktní třída. Polymorfismus datových memberů se dá realizovat konstrukcí "union" nebo kompozicí structů, v nejhorším případě void* odkazem na další privátní data.
Ohledně opouzdření vnitřní logiky, aby některé třídy či jednotlivé member proměnné a metody mohly zůstat "private"... k tomu přece slouží rozdělení zdrojáků do většího počtu drobných "translation units" = do jednotlivých Céčkových souborů (a obvykle k nim přináležejících .H). Céčkový sobor může deklarovat proměnné a funkce "static", takže se neobjeví v tabulce exportovaných symbolů = "nejsou vidět" z jiných translation units. A oddělený hlavičkový soubor bude obsahovat pouze zveřejněné vnější rozhraní. Ono i z hlediska čitelnosti a rozsahu kódu to vychází tak, že jedna "translation unit" (soubor .C) by měl pojednávat cca jednu větší "třídu objektu", nebo pár těsně spřízněných tří, které si mohou či musí vidět navzájem do talíře...
Tohle vše se v kernelu v Céčku samozřejmě používá. Není to tak elegantní jako vyšlapané pěšinky C++, ale přesto to funguje.
Přesně tak. Dám příklad driveru pro zvukovku s čipem ICE1724. Struct driveru definuje sadu metod (pointerů na funkci) s defaultní implementací. Každá zvukovka s tímto kontrolérem (je jich spoustu) bude mít základní funkcionalitu. A konkrétní zvukovka s přidanými funkcemi ve své "translation unit" "přetěžuje" některé z těchto metod svým kódem (dokonce i některé volají metodu "předka" a za to přidají svůj malý štěk). Zvukovka má svůj "odděděný" struct, ve kterém si přepíše příslušné pointery svými přetěžujícími metodami. A když přijde požadavek na novou zvukovku, jejíž jiná funkcionalita do stávajícího modelu nepasuje, buď si přepíše celou tu delší metodu i za cenu většího copy/paste, nebo se ukáže, že základní sada metod není dostatečně obecná (např. princip práce s hodinami) a zrefaktoruje se to v základu na obecnou/konkrétní vrstvu.
Proč se zde snažíte o dědičnost a polymorfismus, když ani jedno není jádrem OOP? Dědičnost se tu již probírala a polymorfismus je JEN JEDNÍM důsledkem zasílání zpráv. Popsal jste tu jakési zapouzdření, ale jak požádáte ve vašem „objektu“ o spuštění „metody“, kterou nemá? Teprve až tohle pochopíte, pochopíte taky, proč struct nemůže být objektem.
Protože se tím mění mechanismus řízení běhu programu, kdy iniciátor operace již nemusí nic vědět o struktuře dotazované entity, což posunuje okamžik rozhodnutí na později, čímž zvyšuje zaměnitelnost oné cílové entity a tím obecnost či znovupoužitelnost (a tím jednoduchost) kódu. To(!) bylo cílem Kaye.
Jako nejjednodušší ukázku je možno si v různých jazycích zkusit vyrobit proxyobjekt.
Doporučuji kliknout na zdroj a přečíst si to. Je tam dobré a stručné zhodnocení celé 6000 stránkové eseje. Nejvíc se mi líbí věta " OOP provides developers too many tools and choices, without imposing the right kinds of limitations.". Říkal jsem si, proč některé projekty vypadají, jako když zamknete přes noc děti do cukrárny, a ráno je najdete přiotrávené ve zdemolovaném podniku :-D .
U javy je vidět že se OOP dodělávslo expost. Vůbec je ten jazyk podobně jsko php obětí své vlastní historie.
Podle mě správně použité OOP velmi zvyšuje čitelnost kódu. Navrhnout dobře základní strukturu objektu je ovšem klíčové. Daleko přehlednější je pro mě ruby. Tam kde jde o performance možná něco jako rust nebo stresy dobrý Object Psscal