PHP OOP

dl

PHP OOP
« kdy: 01. 09. 2012, 16:05:08 »
Pěkný den, jsem začátečník v PHP OOP. Mam vytvořeny dvě třídy. Jednu na generování zpráv a druhou pro připojení k databázi.
Chtěl bych metody třídy Zpráva použít ve třídě Databáze, kde mi budou generovat chybové hlášky. Jak na to?

Ještě bych se chtěl zeptat co vše by měla třída Databáze umět, jestli všechny metody dát do jedné třídy nebo vytvořit více specializovaných na dotazy do DB, připojení a výběr DB atd.

Děkuji.


DK

Re:PHP OOP
« Odpověď #1 kdy: 01. 09. 2012, 17:13:20 »
ad 1. vytvorit v tride Databaze instanci tridy Zpravy a pomoci toho pouzivat dane metody, nebo druha vec, udelat metody tridy Zpravy jako staticke a ty tam pak pouzivat (zalezi, co presne ty metody delaji)

ad2. zalezi, na co tu tridu budes pouzivat, nicmene ja osobne delam jednu tridu Databaze, ktera obsahuje vsechno

dl

Re:PHP OOP
« Odpověď #2 kdy: 01. 09. 2012, 17:35:03 »
Děkuji moc za radu.

Zatím třída Message obsahuje vlastně jen metodu getMessage, která přijíma jako parametry "typ" a "obsah" zprávy.
Podle typu ji pak obaluji css třídami z Twitter Bootstrap, http://twitter.github.com/bootstrap/components.html#alerts

Povedlo se mi ve třídě databáze v konstruktoru vložit třídu Message a pak v metodách používám Message::getMessage($typ, $obsah), udělal jsem metodu uvnitř třidy jako statickou.



Re:PHP OOP
« Odpověď #3 kdy: 01. 09. 2012, 18:30:08 »
Ja tu vidím problém v prístupe. Prečo by Databáza mala vedieť, že existuje niečo ako Správa? Trieda Databáza by mala podľa mňa obsahovať metódy týkajúce sa prístupu k databáze. Ak pošleš kus kódu, pomohli by sme viac

klw

Re:PHP OOP
« Odpověď #4 kdy: 01. 09. 2012, 20:04:43 »
Ja tu vidím problém v prístupe. Prečo by Databáza mala vedieť, že existuje niečo ako Správa? Trieda Databáza by mala podľa mňa obsahovať metódy týkajúce sa prístupu k databáze. Ak pošleš kus kódu, pomohli by sme viac

Ano, přesně tak. Třída pro přístup k databázi je poměrně nízkoúrovňová, proto by neměla rozhodovat o tom, co se stane s chybou, čili zda se vygeneruje zpráva, nebo zda se stane něco jiného. Čistější postup je vyhodit výjimku a tu zpracovat na vyšší vrstvě, protože co když budeš chtít tu databázovou třídu použít opakovaně na jiném místě, kde budeš chtít chyby zpracovat jinak než zasíláním zpráv?



klw

Re:PHP OOP
« Odpověď #5 kdy: 01. 09. 2012, 20:19:22 »
Ještě bych se chtěl zeptat co vše by měla třída Databáze umět, jestli všechny metody dát do jedné třídy nebo vytvořit více specializovaných na dotazy do DB, připojení a výběr DB atd.

Nejsem sice odborník na PHP, ale snad i zde bude fungovat běžný OOP DAO pattern. Já bych udělal třídu s daným rozhraním pro ukládání a načítaní objektu/více objektů, např. (použita Java syntaxe):
void save(SomeObject object);
SomeObject load(SomeIdentificator id);

+ třeba nějaké metody pro optimalizované dotazy.

Pokud by ukládané dokumenty byly složitější, můžeš si udělat pro každý objekt jednu DAO třídu. Rozhraní metod DAO třídy by rozhodně neměly řešit výběr DB, vytváření připojení apod., to má řešit implementace.

Potom když toto dodržíš, je úplně jedno, jaká bude implementace vespod – můžeš vše nacpat do jedné třídy, a když tam toho bude moc, tak to můžeš rozložit do více tříd, které bude zastřešovat tvá DAO třída, jejíž rozhraní se nezmění, tudíž při změně implementace nebudeš muset měnit kód, který DAO třídu používá. Můžeš třeba i změnit implementaci na ukládání do souboru namísto do databáze, volající nic nepozná.

KapitánRUM

Re:PHP OOP
« Odpověď #6 kdy: 01. 09. 2012, 20:21:49 »
Myslím, že se jedná o log / debug, nevidím jediný důvod, proč to v malém projektu řešit třídou.
OOP je mocná zbraň hlavně v rukou těch, co ním neumí a mohou s ní nadělat pěknou paseku.
Proč prostě nezavolat něco add_to_log ("Databáze je v hajzlu");
Proč to řešit samostatnou třídou?
Nejlepší řešení je to nejjednodušší a opravdu nemá smysl dělat třídu pro každou kravinu.
Něco jiného by to bylo ve velkém megaúberprojektu, tam by dávalo smysl místo connection vracet v resultu třeba chybu.
Jeden můj projekt používá po celém světě určitě pět lidí!! ;D a má asi 5k řádek kódu, ale log je prostě jen seznam.
Dělat pro to třídu by mělo myslím smysl, kdybys chtěl s tou chybou nějak dál pracovat, třeba dát uživateli možnost znovu nastavit connection nebo zadat heslo.

dl

Re:PHP OOP
« Odpověď #7 kdy: 01. 09. 2012, 20:50:36 »
Dělám to prostřednictvím tříd, právě proto že se chci naučit to dělat objektově, naplácat jen funkce už umím. A PHP jsem zvolil proto, že funguje na každém hostingu. Jinak se učím v Javě, kde to jinak nejde, ale web sem v ní ještě nezkoušel. Samozřejmě to není velký projekt, ale nevidím jinou cestu než prostě začít. Nějaké praktické zkušenosti jak postupovat při učení se OOP jako samouk?

Myslel jsem to se zprávami tak, že to nebudej jen log pro mě, ale i výstup například pří instalačním procesu. Databáze OK vs. Problém s připojením.
Mám tedy řešit jako výjimky? Zkusím si to ještě ujasnit. Nejvíc mi dělá problém, že když něco navrhnu, vždycky mi někdo řekne, že by zvolil přesně jiný návrh než mi poradil někdo před tím  :). Více tříd které dědí, málo tříd s hodně metodami, statické metody... OOP někde a funkce kde to není potřeba atd.

Díky moc.

KapitánRUM

Re:PHP OOP
« Odpověď #8 kdy: 01. 09. 2012, 21:05:36 »
OOP je jako řešení "pomocí trojúhelníků", skoro všechno se dá vyřešit pomocí trojúhelníků, ale kruh bývá jednodušší nakreslit pořád pomocí kružítka. Stejně tak k tomu přistupuj, ve své třídě můžeš zapouzdřit přístup k MySQL i PGSQL, ostatně MySQL zadarmo tu už dlouho nebude. To je super příklad toho, kdy je použití třídy dar z nebes. Používáš jeden objekt a přitom je jedno, jakou DB máš.
Tedy, chválím ti, že se učíš OOP, ale zkus se zaměřit na ty části, kde použití OOP dává smysl a vynechat ty části, kde je OOP blbost.
Píšeš o PHP, ale PHP dlouho OOP nebylo a původem je to prostě jen strukturovaný skript.
Neuč se otevřít zuby pivo, zůstane ti to a když to budeš dělat ve slušné společnosti, budou tě mít za podivína.

tadeas

Re:PHP OOP
« Odpověď #9 kdy: 01. 09. 2012, 21:06:02 »
Něco podobného jsem řešil jakousi naivní implementací "observer" patternu (google pokud nevíš o co jde).

V zásadě to vypadalo tak, že třídy, které generují nějaké zprávy, implementují "IObservable" interface. A třídy, které ty zprávy zpracovávají (např. logování do souboru, logování do prohlížeče, logování pro Munin/Nagios/Zabbix, maily...) implementují "IObserver" interface.

Interface vypadají zhruba takto:
Kód: [Vybrat]
interface IObserver
{
    function onMessage($sender, $message, $code);
}

interface IObservable
{
    function addObserver($observer);
    function sendMessage($message, $code);
}
onMessage a addObserver jsou očividné. sendMessage prostě volá onMessage s $message a $code všem observerům v $this->observers, které se nastavují přes addObserver.

Člověk pak třídě přes addObserver dá observery (třeba podle konfiguráku, podle $_GET parametru apod.) a třída pak už volá jenom $this->sendMessage a nestará se, kdo co s tou zprávou stane.

dl

Re:PHP OOP
« Odpověď #10 kdy: 01. 09. 2012, 23:38:36 »
OOP je jako řešení "pomocí trojúhelníků", skoro všechno se dá vyřešit pomocí trojúhelníků, ale kruh bývá jednodušší nakreslit pořád pomocí kružítka.

Já tomu rozumím, že OOP bylo do PHP dodělané a že to jde i jinak. Takže prakticky, chci si udělar RS, který bude nad obyčejnou MySQL databází, bude mít správu uživatelů a příspěvků atd. a při nejlepším se bude moci rozšiřovat. Může se někdo tedy podělit o to jakou strukturu tříd a s jakými metodami bych měl vytvořit? Klidně mi to popište jen ideově, ale objektově. Mě se tedy PHP moc nelíbí, s tím, jak se mění, jak jsou pojmenovávanéné funkce jedna tak, jiná jinak. To pro mě je čitelnější i Lisp nebo Clojure, ale chci to popřípadě komukoliv dát a říci, to poběží všude (tedy PHP) a ještě si říci, že návrh je dobrý a dá se na tom stavět dál i to přepsat v jiném jazyce s OOP přístupem (třeba Java).


Však já s tebou zatočím ty jeden atlete – Muž z Acapulca

KapitánRUM

Re:PHP OOP
« Odpověď #11 kdy: 01. 09. 2012, 23:55:52 »
Jestli chceš dobrý OOP jazyk, tak začni s Java.
Pravda, J2EE je ohromný moloch a začít s ním je jako kdybys autoškolu měl začít dělat hned s raketoplánem, ale Java tě to nutí dělat správně. Nemusíš hned dělat weby.
V PHP se to správně dá dělat taky, ale co je správné řešení, pokud PHP umožňuje některé věci řešit jednoduše, není pak správné je jednoduše používat? Učil jsem OOP spoustu lidí, nějakou dobu vedl kroužek C# a C# je okopčená Java.
Na tvém místě bych si přečetl něco o modelech a začni třeba singletonem.
Zkus to použít, ne jen používat OOP, ale OOP se správným modelem.
Pokud se budeš snažit naučit na motorce tím, že jí budeš nosit na zádech, tak se jen nadřeš a naučíš dělat nesmyslný věci.
Taky se rozhodni v čem chceš vlastně programovat, protože Java a PHP to je jako Mercedes a Tráboš.
Jo, nedávno do Tráboše taky přidali airbag (OOP), ale ještě včera se nafukoval ručně pumpičkou.

klw

Re:PHP OOP
« Odpověď #12 kdy: 02. 09. 2012, 00:02:18 »
Dělám to prostřednictvím tříd, právě proto že se chci naučit to dělat objektově, naplácat jen funkce už umím. A PHP jsem zvolil proto, že funguje na každém hostingu. Jinak se učím v Javě, kde to jinak nejde, ale web sem v ní ještě nezkoušel. Samozřejmě to není velký projekt, ale nevidím jinou cestu než prostě začít. Nějaké praktické zkušenosti jak postupovat při učení se OOP jako samouk?

Samozřejmě by se to dalo "nějak splácat tak, aby to fungovalo", protože aplikaci stejně "nikdo jiný kromě tebe nebude používat". Ale vidím, že ty se naopak snažíš postupovat pečlivě, najít co nejsprávnější řešení. A i když to třeba napoprvé nebude úplně ono, tak myslím, že jsi na dobré cestě, a že se to časem podobým zkoušením, byť i na jednoduchých aplikacích, naučíš ;-)

Jinak zkus při učení se OOP přemýšlet o objektech jako o reálných fyzických objektech, jak je vidíš ty zvenčí, a co ve skutečnosti dělají. Jakou mají zodpovědnost. Například takový vypínač světla na zdi – pro tebe je to jen zařízení, které se dá zmáčnout, čímž se rozsvítí nebo zhasne světlo. Už tě nezajímá, jestli je se světlem propojený dráty, nebo (což je zrovna případ u nás v práci) je to bezdrátový ovladač, který ovládá světla "dálkově". Stejně tak tvoje databázová třída by měla oddělovat implementaci perzistence objektů od vyšších vrstev, kterým je úplně jedno, jestli data budou uložená v databázi, v souboru, na nějaké web-service, nebo kdo ví, kde jinde. Pro ně je pouze důležité, že ta data budou uložena, nechtějí řešit nic víc...

Myslel jsem to se zprávami tak, že to nebudej jen log pro mě, ale i výstup například pří instalačním procesu. Databáze OK vs. Problém s připojením.
Mám tedy řešit jako výjimky? Zkusím si to ještě ujasnit. Nejvíc mi dělá problém, že když něco navrhnu, vždycky mi někdo řekne, že by zvolil přesně jiný návrh než mi poradil někdo před tím  :).

...a naopak zase databázová třída by neměla vědět, co s chybami chceš dělat, ale to už jsem psal. Výjimky určitě nejsou jediné řešení, ale mysli na to, že co použiješ v databázové třídě, to budeš muset používat ve všem, co tu databázovou třídu bude volat. Pokud tam nasadíš nějakého kočkopsa, tak ti pak bude smrdět všude, proto se snaž najít nějaké co nejvíce univerzální řešení, které nezavádí příliš mnoho závislostí na tvých vlastních třídách, jinak každé chyby v návrhu budeš litovat.

Více tříd které dědí, málo tříd s hodně metodami, statické metody... OOP někde a funkce kde to není potřeba atd.
Pokud budeš využívat rozhraní (doufám, že PHP stejně jako Java má interface), tak pak bude úplně jedno, jestli více nebo málo tříd. Vyšší vrstva bude využívat jen to rozhraní a bude od něj očekávat, že jeho implementace bude dělat to, co má.

Statické metody doporučuji (alespoň v Javě) používat co nejméně (kromě oprávněných případů), ale vysvětlení důvodu by bylo asi na delší diskuzi. V krátkosti: hůře se pak řeší zaměnitelnost jinou implementací.

dl

Re:PHP OOP
« Odpověď #13 kdy: 02. 09. 2012, 00:03:33 »
Rozumím vám, mě se Java líbí. Vykašlu se na PHP a nezaleknu se Mercedesu, když vlastně chci také jezdit po dálnici  :D

Alt+F4

Re:PHP OOP
« Odpověď #14 kdy: 02. 09. 2012, 03:13:52 »
Ehm...vážně se mi nezamlouvá způsob jakým je PHP věčně zadupáváno do země. Přirovnání Mercedesu (Javy) a Tráboše (PHP) je trochu přehnaný, ale budiž. Něco pravdy na tom je. Jen je třeba si vzpomenout pro kterou klientelu byly auta (i jazyky) určeny. Třeba Meďour nikdy nebyl stavěnej na naše český polňačky, i když se jim nadává do dálnic a zároveň si nikdo nebude kupovat Mercedes, když si chce dojet pro pár lahváčů do sámošky. Nebo pro tuzemák :-)

Ruku na srdce, kdo měl tu kliku a dělal web, který se může pochlubit třeba 100k/d návštěvností? Většina webů jsou nejsou ani tak velký ani tak vytížený. I kdyby byly, pořád nevidím důvod, proč by to PHP nemělo zvládnout. Kterej web se dá napsat v J2EE a v PHP ne? Xichtokniha (čti Facebook) jede taky na Trábošovi a ten je s vytížením úplně jinde. Takže pokud budu dělat jakýkoliv web normální velikosti, proč se mám učit molocha J2EE? Je to jako s kanónem na vrabce...

S tím lepením OOP do PHP...nebylo taky náhodou OOP přilepovaný třeba do Céčka? Není C++ stejný hybrid jako PHP? Myslím, že v obojím můžeš psát procedurálně i objektově. Přesto se o obou dá mluvit jako o úspěšných jazycích. Jasně, v PHP jsou "perly", který lezou krkem, ale vzpomínám si taky na diskuze javistů i céčkařů a ti měli ze svýho jazyka taky slušný headache...

Někde na zdrojáku nebo rootu byl zveřejněn průzkum jak si stojí server-side jazyky na serverech. No, Java se svými 4% mě hodně zklamala. Nevím jakou metodikou se došlo k těm cifrám, ale asi to nebude asi tak daleko od pravdy. Stejný výsledky jsem našel zde:

http://w3techs.com/technologies/overview/programming_language/all

A teď se musím zase přiklonit k názorům co tu už padly. Bohužel já šel směrem Pascal->Assembler->C->PHP->Java. Faktem je, že u PHP2.0/FI to bylo až do PHP4 ok, u PHP5 s OOP jsem byl mimo, protože jsem neuměl myslet objektově. Pak jsem se to naučil a lákala mě Java a tam jsem narazil, protože OOP v Javě a PHP je vážně jiný kafe. Design patterns pro Javu nebudou úplně stejný i pro PHP. Už jen tím, že třeba PHP není silně typovaný jazyk, nezná výčtové typy, generiku, vlákna atd. Proto se o phpčkařích říká, že jsou to bastlíři. Někdo ano, někdo ne. Ale je to taky dané tím, co ti jazyk umožňuje. V PHP se naučíš poloviční OOP a taky snadno můžeš sejít z cesty.

Takže rada: vybodni se na PHP a zůstaň u Javy. Naučíš se lepším návykům a nebudeš v tom mít zbytečně bramboračku. Nauč se základních cca 13 návrhových vzorů pro Javu nebo C#, poznáš v tom řešení svýho problému a ušetříš si moře času nedokonalým PHP.

Mimochodem, prasit se dá ve všem. V Javě, PHP a dost možná i v Karlovi :-)