Jason Citron končí jako CEO Discordu. Od pondělí 28. dubna nastupuje nový CEO Humam Sakhnini, bývalý CSO Activision Blizzard.
Článek na Libre Arts představuje baskytarový multiefekt Anagram od společnosti Darkglass Electronics. S Linuxem uvnitř (licence, GitHub).
Městský soud v Praze vyhlásil rozsudek, který vyhověl žalobě novináře Jana Cibulky, který s podporou spolku IuRe (Iuridicum Remedium) požadoval omluvu od státu za to, že česká legislativa nařizuje operátorům uchovávat metadata o elektronické komunikaci. To je přitom v rozporu s právem. Stát se musí novináři omluvit a zaplatit náklady řízení. Především je ale součástí přelomové rozhodnutí o nelegálnosti shromažďování dat a o
… více »Americké technologické firmy Apple a Meta Platforms porušily pravidla na ochranu unijního trhu, uvedla včera Evropská komise (EK). Firmám proto vyměřila pokutu – Applu 500 milionů eur (12,5 miliardy Kč) a Metě 200 milionů eur (pět miliard Kč). Komise to oznámila v tiskové zprávě. Jde o první pokuty, které souvisejí s unijním nařízením o digitálních trzích (DMA). „Evropská komise zjistila, že Apple porušil povinnost vyplývající z nařízení
… více »Americká společnost OpenAI, která stojí za chatovacím robotem ChatGPT, by měla zájem o webový prohlížeč Chrome, pokud by jeho současný majitel, společnost Google, byl donucen ho prodat. Při slyšení u antimonopolního soudu ve Washingtonu to řekl šéf produktové divize ChatGPT Nick Turley.
Po roce vývoje od vydání verze 1.26.0 byla vydána nová stabilní verze 1.28.0 webového serveru a reverzní proxy nginx (Wikipedie). Nová verze přináší řadu novinek. Podrobný přehled v souboru CHANGES-1.28.
Byla vydána nová verze 10.0.0 otevřeného emulátoru procesorů a virtualizačního nástroje QEMU (Wikipedie). Přispělo 211 vývojářů. Provedeno bylo více než 2 800 commitů. Přehled úprav a nových vlastností v seznamu změn.
42 svobodných a otevřených projektů získalo finanční podporu od NLnet Foundation (Wikipedie).
Americký výrobce čipů Intel plánuje propustit více než 20 procent zaměstnanců. Cílem tohoto kroku je zjednodušit organizační strukturu ve firmě, která se potýká s problémy.
Byla vydána OpenMandriva Lx 6.0 s kódovým názvem Vanadium. Přehled novinek v poznámkách k vydání.
$a = new A();
Což je na tvrdo globální namespace - zkoušel sem čachrovat s use NS; atd. ale bez úspěchu $trida = Model::factory('JmenoTridy');A v té statické metodě factory ošéfovat co je třeba. V krajním případě tohle použiju, děkuju za návrh! Nenapadá někoho něco ještě lepšího? Nejraději bych psal:
$trida = new JmenoTridy();Ale zdá se, že tohle nemá řešení
namespace NS; class A extends \A { }Pro požadavek 2) zavolám v jádře:
... $a = new A(); ...Interpret nahraje třídu z jádra... donutit na jinou ho dokážu pouze konstruktem uses, ale pak nebude fungovat varianta, kdy nová třída neexistuje. Opravdu si začínám myslet, že to prostě nemá řešení a budu muset udělat nějaký workaround typu factoring... Díky
vymyslím si, že v jedné implementaci chci aby metoda A::X vracela jiný výsledekJak moc jiný?
při vytváření instance ve zbytku aplikace volám: $a = new A();Proč to nemůžete ve zbytku aplikace volat jinak?
vymyslím si, že v jedné implementaci chci aby metoda A::X vracela jiný výsledekJak moc jiný?
Typicky jde o customizace nějaké obecné metody. Např. metoda standardně vypisuje všechny soubory v adresáři, ale já chci v jedné implementaci, aby nevypisovala skryté (.*) - tedy zdědím, předeklaruju tu metodu, ta zavolá původní metodu a profiltruje výsledek na .*
při vytváření instance ve zbytku aplikace volám: $a = new A();Proč to nemůžete ve zbytku aplikace volat jinak?
Ne včechna užití té třídy jsou napsaná mnou - využívám framework.
Před chvílí sem s kolegou vykoumal řešení, které mi příjde akceptovatelné: core třída i ta implementační budou mít jméno s nějakým prefixem a v autoloaderu zařídím vedle require příslušného souboru také vytvoření aliasu třídy na "bezprefixový zápis". Např.
// deklaruju core v souboru $core_prefix/A.php class Core_A {}; // deklaruju změněnou třídu v souboru $implementacni_prefix/A.php class Implementace_A extends Core_A {} // v běžném kódu používám $a = new A(); // popř. class B extends A {} // v autoloaderu podle jména třídy najdu správný include require_once($classname); class_alias($prefix.$classname, $classname);Nic lepšího asi nevymyslím
Např. metoda standardně vypisuje všechny soubory v adresáři, ale já chci v jedné implementaci, aby nevypisovala skryté (.*) - tedy zdědím, předeklaruju tu metodu, ta zavolá původní metodu a profiltruje výsledek na .*Není jednodušší nechat tu původní metodu bejt a udělat si ten filtr bokem?
$fileFinder = new FileFinder(); $filter = new NoHiddenFilesFilter($fileFinder->getFiles()); $files = $filter->getFiltered();Nebo použít dekorátor
$baseFileFinder = new FileFinder(); $noHiddenFilesFinder = new NoHiddenFilesFinder($fileFinder); $files = $noHiddenFilesFinder->getFiles();V obou případech nemusíte na původní třídu ani hrábnout.
class aplikace -(1)-> class fileFinder -(2)-> class htmlRendererRozhodnu se, že chci upravit fileFinder diskutovaným způsobem. A mám následující možnosti: 1) aplikace musí být naprogramovaná tak, že umí nahradit třídu fileFinder jinou (např. v konfiguráku bude jméno třídy) 2) fileFinder musí mít rozhraní pro aplikování vybraných operací s možností ovlivnit výsledné chování - tedy fileFinder musí mít rozhraní pro pluginy a v runtime někde uloženou jejich konfiguraci - to je Vaše řešení? 3) do místa (1) vložím vlastní kód, který udělá co bude potřebovat, využije třeba alternativní třídu pro fileFinder, ale pak musí zajistit volání htmlRendereru v kroku (2) sám 4) řešení co sem navrhl odpoledne - tedy nějak elegantně zařídím, aby celá aplikace používala místo třídy fileFinder úplně jinou třídu (potomka původní nebo implementující stejný interface) Varianta 1) a 2) je OK, ale vyžaduje předem vyspecifikované podporované změny chování aplikace. Každé rozšíření těchto možností znamená netriviální úpravu aplikace. Navíc tato řešení neumí měnit předky používaných metod. Neumí se "vklínit" do posloupnosti dědění, a nahradit pouze jeden článek. Takto je možné pouze v libovolném místě řetěz dědění přetnout a pak znovu doimplementovat až do finálních tříd (tedy redundance kódu a druhotně podobný nešvar jako má 3) Varianta 3) se mi hrubě nelíbí. Vyžaduje dost redundantní práce. Co říkáte na Variantu 4)?
Pokud je tohle posloupnost volání, tak to je instance něčeho co pracovně nazývám architektura trubka nebo štafeta. Tam máte natvrdo zadrátovánou tu šipku č. 2 a nemůžete s tím nic udělat. To je váš hlavní problém, kterého se potřebujete zbavit. Pokud byste volání předělal takto:class aplikace -(1)-> class fileFinder -(2)-> class htmlRenderer
class aplikace -> class fileFinder <- $files -> class htmlRendererTak s tím můžete pak dělat co chcete.
varianta (A): nezávisle fungující Finder a Filter class aplikace -> class fileFinder <- $files -> class fileFilter <- $filteredFiles -> class htmlRenderernebo
varianta (B): Dědění nebo lépe Dekorátor class aplikace -> class filteredFileFinder -> class fileFinder <- $files <- $filteredFiles -> class htmlRenderer
Mým cílem je aplikace, která něco umí a je možné ji co nejširším způsobem a s co nejmenčí redundancí kódu upravovat.Můžete tohle aplikovat na stávající požadavky, nebo ty, které s nějakou rozumnou pravděpodobností očekáváte, ale nemůžete udělat univerzální stroj.
1) aplikace musí být naprogramovaná tak, že umí nahradit třídu fileFinder jinou (např. v konfiguráku bude jméno třídy)To je klasický příklad použití vzoru Factory.
varianta (C): Factory $className = getConfigOption("fileFinderClass"); $factory = new FileFinderFactory(); $fileFinder = $factory->createFileFinder($className);
2) fileFinder musí mít rozhraní pro aplikování vybraných operací s možností ovlivnit výsledné chování - tedy fileFinder musí mít rozhraní pro pluginy a v runtime někde uloženou jejich konfiguraci - to je Vaše řešení?To by byl následující kód:
varianta (D): Filter jako plugin funkcionalita Finderu $filter = new WhateverFilter(); $fileFinder = new FileFinder($filter); $files = $fileFinder->getFiles();To je ještě další varianta, kterou můžete použít.
3) do místa (1) vložím vlastní kód, který udělá co bude potřebovat, využije třeba alternativní třídu pro fileFinder, ale pak musí zajistit volání htmlRendereru v kroku (2) sámTo je něco čemu byste se měl vyhnout - fileFinder by měl výsledek vracet a ne štafetově předávat a mělo by mu být úplně jedno kdo ho zavolal a komu ten výsledek vrátí. Pak nebude problém s vložením kódu.
4) řešení co sem navrhl odpoledne - tedy nějak elegantně zařídím, aby celá aplikace používala místo třídy fileFinder úplně jinou třídu (potomka původní nebo implementující stejný interface)Tím pouze používáte pneumatické kladivo tam kde stačí trochu ťuknout hřebíček.
Neumí se "vklínit" do posloupnosti dědění, a nahradit pouze jeden článek.Proto se dědění moc nepoužívá - vytváří vazby moc natvrdo. Pokud tam potřebujete něco vklínit, je lepší použít volnější vazby, viz příklady. V kódu nahoře jsem označil varianty ABCD, chtěl bych shrnout výhody a nevýhody každé: A) (nezávislé třídy Finder a Filter) nejobecnější možnost, kde ani jedna třída neví o jiné - můžete kombinovat všechno se vším a udělat téměř jakékoliv chování. B) (Filter jako dekorátor nad Finderem) něco jako dědění, můžete před a po volání základního Finderu provést libovolnou modifikaci a vrátit výsledek ve stejném formátu. Oproti dědění můžete ty modifikace libovolně nabalovat na sebe a to i v době běhu aplikace. C) (Factory) výroba různých komponent (Finderů, Filtrů, ...) je schována na centrální místo, a případně konfigurovatelná uživatelem. Řekl bych, že to je spíš doplňková záležitost k ostatním variantám. D) (Plugin Filter) implicitně předpokládáte že se nějaký filtr použít musí, byť třeba prázdný. Hodí se, pokud je hodně jednoduchých Filtrů ale třeba jen jeden Finder. Místo jednoho filtru můžete třeba pluginovat pole filtrů atd.
...nejspíš tedy půjdu cestou "pneumatického kladiva"Akorát že, i když tu třídu nahradíte v runtime nebo nějakým hackem s include, tak nevyřešíte podstatu problému a to sice, že budete mít pořád na krku tu odpornou povinnost v náhradní třídě volat ten htmlRenderer.
C) souhlasím, dobrá věc, ale dělat tak všechny třídy v celé aplikaci je IMO nesmysl (a ani to nejde)Jsou na to frameworky.
Myslím, že ne... resp. šikovným designem metod docílím toho, že bude nějaká "worker" metoda, kterou můžu měnit a další metody zařídí začlenění do systému - těch se dotýkat nebudu (moct). Navíc je tak velice elegantně vyřešeno automatické používání nové funkčnosti v celém systému....nejspíš tedy půjdu cestou "pneumatického kladiva"Akorát že, i když tu třídu nahradíte v runtime nebo nějakým hackem s include, tak nevyřešíte podstatu problému a to sice, že budete mít pořád na krku tu odpornou povinnost v náhradní třídě volat ten htmlRenderer.
Jako např? ...jak řeší dědění z těchto tříd? Nechci už moc prudit, odkaz na doc úplně stačíC) souhlasím, dobrá věc, ale dělat tak všechny třídy v celé aplikaci je IMO nesmysl (a ani to nejde)Jsou na to frameworky.
šikovným designem metod docílím toho, že bude nějaká "worker" metoda, kterou můžu měnitSuper, to zní dobře.
Jako např? ...jak řeší dědění z těchto tříd? Nechci už moc prudit, odkaz na doc úplně stačíZkuste se podívat/inspirovat např. http://substrate-php.org/ případně existuje asi kopa alternativ... hledejte "php ioc framework". Dědění (implementace) bych doporučil na nějaký čas úplně vynechat a zkusit to řešit přes ten "šikovný design"...Díky!
Tiskni
Sdílej: