Swift a protected access control

SB

Re:Swift a protected access control
« Odpověď #15 kdy: 22. 12. 2017, 10:29:36 »
Co si myslíte o tom, že Swift od Applu nemá protected a tedy nelze mít property/metody, které by šlo použít pouze v rámci hierarchie dědičnosti a ne zvenčí?

Že jste přišel o klíčový prvek OOP - zapouzdření. Tím se závažně mění koncepce výpočtu (i když ne každý je schopen to pochopit, což se ukáže v diskusi).

Četl jsem jeden článek, kde důvod byl asi takový, že v podstatě protected je k ničemu a žádnou ochranu přístupu neposkytuje, protože nikomu nebrání třídu podědit a prvek zveřejnit jako public.

A který pičus ho napsal? Jak se dostanete do instance třídy A k její neveřejné vlastnosti BŽ pomocí zděděné třídy B implementující veřejný přístup k BŽ? Těžko budete v instanci A používat metodu z B.

Jenže teď dám příklad, např. třída Thread mívá často nějakou protected metodu run, která je určena pro překrytí a je volána, když se vlákno nastartuje. Ve Swiftu by nic nebránilo tu metodu run zavolat napřímo, což je v podstatě programátorská chyba...

Ona metoda run je nevěřejná z nějakého důvodu, a to toho, že objekt je výhradním řešitelem problému. V okamžiku, kdy máte pseudozapouzdření (Python) nebo žádné zapouzdření a run zavoláte, tak jste to posral, protože se s tím nepočítalo. A posrat to jde.


SB

Re:Swift a protected access control.
« Odpověď #16 kdy: 22. 12. 2017, 10:41:13 »
No jasně. To známe. Ale já se ptám proč by to tak mělo být řešené? Není to poněkud zbytečně složité? Proč to prostě není v té metodě start?

Vy víte, co se děje mezi začátkem start a spuštěním run?

SB

Re:Swift a protected access control.
« Odpověď #17 kdy: 22. 12. 2017, 10:43:12 »
budu předávat funkci start anonymní funkci, která se bude v tom vláknu / vlákench vykonávat?

To samozřejmě jde, používá se to např. v Pythonu nebo Smalltalku.

SB

Re:Swift a protected access control.
« Odpověď #18 kdy: 22. 12. 2017, 10:45:01 »
Dědičnost je zbytečná skoro vždy.

Rozlišujte názor od prokazatelné skutečnosti.

ooooop

Re:Swift a protected access control.
« Odpověď #19 kdy: 22. 12. 2017, 10:49:46 »
Dědičnost je zbytečná skoro vždy.

Rozlišujte názor od prokazatelné skutečnosti.

+1


gll

Re:Swift a protected access control.
« Odpověď #20 kdy: 22. 12. 2017, 10:53:08 »
budu předávat funkci start anonymní funkci, která se bude v tom vláknu / vlákench vykonávat?

To samozřejmě jde, používá se to např. v Pythonu nebo Smalltalku.

používá se to téměř všude i v c/c++. V boost::thread předáváte funkci konstruktoru.

gll

Re:Swift a protected access control.
« Odpověď #21 kdy: 22. 12. 2017, 11:03:03 »
Dědičnost je zbytečná skoro vždy.

Rozlišujte názor od prokazatelné skutečnosti.

prokazatelná skutečnost je, že použití dědičnosti v tomto případě prodlouží kód.

BoneFlute

  • *****
  • 1 981
    • Zobrazit profil
Re:Swift a protected access control.
« Odpověď #22 kdy: 23. 12. 2017, 00:06:32 »
No jasně. To známe. Ale já se ptám proč by to tak mělo být řešené? Není to poněkud zbytečně složité? Proč to prostě není v té metodě start?

Vy víte, co se děje mezi začátkem start a spuštěním run?
Měl bych to řešit? Měl bych to vědět?

Sten

Re:Swift a protected access control
« Odpověď #23 kdy: 23. 12. 2017, 11:45:37 »
Mě ta argumentace přijde nesmyslná. Protected je contract. Je vhodné, když kompilátor při přímém přístupu k protected proměnné zařve, že tohle asi není to, co programátor chtěl udělat, ale programátor by měl mít možnost to obejít, pokud se domnívá, že to potřebuje obejít. Proto zrušit protected se zdůvodněním, že programátor ho může obejít, je nesmysl; to není chyba zapouzdření, to je vlastnost toho, že programy tvoří programátor.

U čeho mi naopak uniká rozumný důvod, proč existuje, je private. Poděděná třída má mít možnost přistupovat k vnitřnímu stavu děděné třídy, jinak je dědění velmi omezené (v používaných analogiích private ani nedává smysl, pokud Plachetnice dědí Loď, tak má přeci přístup ke všem vlastnostem Lodi). Vím o případech, kdy jsou nějaké vnitřní stavy, kde přístup poděděné třídy nedává smysl, ale ještě jsem neviděl případ, kdy by to nebylo způsobené tím, že si programátor usnadnil práci a nedostatečně dekomponoval ten objekt (třeba u té Lodi tím, že nějaké fyzikální vlastnosti nechal počítat přímo Loď, ale Loď přeci fyziku nedefinuje). Ještě nikdy jsem neviděl případ, kdy by private byl opravdu potřeba, naopak jsem viděl mnoho případů, kdy neuvěřitelně házel klacky pod nohy (C++ STL je velmi dobrý příklad).

BoneFlute

  • *****
  • 1 981
    • Zobrazit profil
Re:Swift a protected access control
« Odpověď #24 kdy: 23. 12. 2017, 19:04:03 »
... Protected je contract. ...

U čeho mi naopak uniká rozumný důvod, proč existuje, je private. Poděděná třída má mít možnost přistupovat k vnitřnímu stavu děděné třídy, jinak je dědění velmi omezené ...

Pointa protected a private je v tom, že private je interní problém daného objektu. Ten si pomocí něho řeší své problémy, které ale nechce zveřejňovat z dobrého důvodu: jakmile to zveřejní, stane se to součástí api, a už to nesmí změnit. Jinak rozbije uživatele. A čím šiřší api, tím více kombinací musí programátor ošéfovat. Když je to private, tak to může kdykoliv přepsat. To je děsně osvobozující.

U protected v praxi vidím zlozvyk programátorů, kteří místo toho, aby metodě dali private, tak jí dají raději protected, protože co kdyby to někdy chtěli přetížit že jo. Když by dávali protected namísto public, tak mlčím.

vyvojar

Re:Swift a protected access control
« Odpověď #25 kdy: 23. 12. 2017, 20:33:15 »
Jo tak jsem to nakonec udělal, že vlákno má property typu Runnable, což je protocol s jednou metodu run.  Property je jen getter a je to na programátorovi, aby si třídu podědil a ten getter překryl a vracel to, co je specifické pro jeho thread. Dobrý to je v tom, že se nestane, že by mu tam někdo přes setter nastavil instanci, kterou nepředpokládá. A nějaký ty featury jako vytvoření instance vlákna z closuru apod.. to se dá udělat přes extension, případně to tam můžu klidně přidat jako statickou metodu. No prostě teď mi to přijde jako nej řešení.

Ta absence protected je ale dost napytel no. V apple kódech jsou snad komenty typu, že toto nemá být používáno jako public, i když to public je, protože tam prostě není protected :)

gll

Re:Swift a protected access control
« Odpověď #26 kdy: 23. 12. 2017, 20:54:57 »
Jo tak jsem to nakonec udělal, že vlákno má property typu Runnable, což je protocol s jednou metodu run.  Property je jen getter a je to na programátorovi, aby si třídu podědil a ten getter překryl a vracel to, co je specifické pro jeho thread. Dobrý to je v tom, že se nestane, že by mu tam někdo přes setter nastavil instanci, kterou nepředpokládá. A nějaký ty featury jako vytvoření instance vlákna z closuru apod.. to se dá udělat přes extension, případně to tam můžu klidně přidat jako statickou metodu. No prostě teď mi to přijde jako nej řešení.

Ta absence protected je ale dost napytel no. V apple kódech jsou snad komenty typu, že toto nemá být používáno jako public, i když to public je, protože tam prostě není protected :)

proč vůbec něco takového děláš a nepoužiješ standardní knihovnu?

vyvojar

Re:Swift a protected access control
« Odpověď #27 kdy: 23. 12. 2017, 21:26:24 »
Jo tak jsem to nakonec udělal, že vlákno má property typu Runnable, což je protocol s jednou metodu run.  Property je jen getter a je to na programátorovi, aby si třídu podědil a ten getter překryl a vracel to, co je specifické pro jeho thread. Dobrý to je v tom, že se nestane, že by mu tam někdo přes setter nastavil instanci, kterou nepředpokládá. A nějaký ty featury jako vytvoření instance vlákna z closuru apod.. to se dá udělat přes extension, případně to tam můžu klidně přidat jako statickou metodu. No prostě teď mi to přijde jako nej řešení.

Ta absence protected je ale dost napytel no. V apple kódech jsou snad komenty typu, že toto nemá být používáno jako public, i když to public je, protože tam prostě není protected :)

proč vůbec něco takového děláš a nepoužiješ standardní knihovnu?

Já standardní knihovnu používám, ale opravdu jen tu standardní knihovnu. Ne ten Foundation (https://github.com/apple/swift-corelibs-foundation), kde jsou věcí jako mutexy, vlákna, to si implementuju sám, protože mi to z toho Foundation nevyhovuje.
Např. v té vlastní implementaci wrapperu nad nativním vláknem to mám udělané tak, že je tam nějaká metoda finish, která se volá pro každé vlákno VŽDYCKY než doběhne, i když ho někdo zruší třeba přes pthread_cancel. Takže to moje vlákno má pěkně jasnej a kontrolovanej životní cyklus.To bych s tím vláknem z Foundation nedokázal, protože je strašně simple wrapper nedomyšlenej.