pátek 27. dubna 2007

Java EE5 - stand-alone client

V minulém článku jsem nastínil, jakým způsobem se dá vyvíjet enterprise aplikace psaná v Jave. Samozřejmostí je využití různých metodik, podle kterých se řídí celý vývojový tým. Dříve, než mohu řešit rozsáhlé aplikace, musím ovšem míti dostatek zkušeností a znalostí. Já se chci více zaměřit na menší problémy, na které začátečník (stejně jako já) může narazit.

Budu předpokládat, že máte již základní znalosti o tom, co je to EJB, JPA a k čemu jsou enterprise aplikace určeny. Pokud by někdo hledal zdroj informací, osobně doporučuji tento tutoriál. Samotné čtení není nijak náročné. Předpokladem je základní znalost OOP, Javy, popřípadě databázových systémů typu Oracle, MySQL, .....

Osobně jsem si po přečtení celého tutoriálu udělal obrázek o tom, co je to vlastně Java EE 5 a k jakým účelům mohu něco tak rozsáhlého využít. V dnešní době je velký boom webových aplikací, které na nás srší ze všech stran. U samotné Javy se domnívám, že to není zrovna nejjednodušší oblast, kterou by se mělo začínat. Osobně jsem se raději více zaměřil na desktop, kde pomocí Swingu jsem schopen vytvořit "sexy" aplikaci, která bude splňovat základní podmínky. Každému, kdo s Javou začíná, doporučuji právě desktop.

Nyní již k samotné stand-alone aplikaci:

Přístup k EJB se dělí na dvě části:

  • Lokální (@Locale)

  • Vzdálený (@Remote)



O tom, který přístup daná EJB využívá se definuje anotací nad samotným interfacem, který samotná beana implemetuje:
@Remote
public interface UzivateleFacadeRemote {
public List findAll();
}


Rozdíl mezi Locale a Remote je ten, že Remote může volat aplikace, která běží v jiné VM. To se samozřejmě hodí ve chvíli, kdy potřebujeme napsat desktopovou aplikaci, která poběží na klientovi, který má vlastní instalaci JRE. Jiná VM není podmínkou pro běh Remote EJB.
Možná někoho napadne, proč tedy všude nevyužít Remote, když mohu volat tuto EJB kdekoli. Důvodem je výkon. Proto, pokud volám EJB uvnitř glassfishe (aplikační server), využiji k tomu Locale. Dost často mi z toho vychází, že implementuji obě interface na beanu. Navíc je také rozdílný způsob volání Locale a Remote EJB.

To by bylo k business logice. Vytvoříme si jednoduchou EJB, která bude mít Remote interface, kterou poté vystavím (deploy) na glassfish.

Nyní, se pustím do desktopové aplikace, která poběží na klientech a bude vzdáleně volat EJB ze serveru.

Prvním předpokladem je přidání celého EJB projektu v podobě distribuovaného jar souboru do aplikace. Jinými slovy, musí být někde, kde na něj samotná aplikace uvidí. V netbeans stačí do library includovat náš "projekt-ejb". Automaticky se hledá distribuovatelný jar soubor, který se defaultně nachází v adresáři dist.
Dále je potřeba přilinkovat tyto soubory:

  • appserv-admin.jar

  • appserv-deployment-client.jar

  • appserv-ext.jar

  • appserv-rt.jar

  • javaee.jar



Všechny uvedené soubory naleznete v adresáři instalovaného glassfishe (GLASSFISH_PATH/lib).

Tím bychom měli připravenou stand-alone aplikaci k tomu, aby nám byla schopna vzdáleně volat EJB.

Nyní již k samotnému kódu:
Properties properties = System.getProperties();
properties.setProperty("org.omg.CORBA.ORBInitialHost", );
properties.setProperty("org.omg.CORBA.ORBInitialPort", );
Context ctx = new InitialContext(properties);
// po pripravene inicializaci vzdalene zavolam EJB
UzivateleFacadeRemote facade = (UzivateleFacadeRemote) ctx.lookup("RemoteName");


Za a dosadíme vlastní parametry pro volání na server. Výchozím portem je 3700. Pokud testuji aplikaci na localhostu pod stejnou VM, jako mám server, není třeba properties nastavovat. Mohu zavolat InitialContext bez properties. Druhou možností je také nastavit parametricky tyto údaje. Pro další informace doporučuji glassfish: EJB FAQ.

Zapoměl jsem zmínit jednu důležitou věc. Pokud vzdáleně volám EJB, musím někde nastavit JNDI (název, pod kterým je vzdálená aplikace schopna nalézt EJB). Existuje několik možností, buď definovat daný název pomocí XML nebo pomocí anotací.

Záměrně jsem některé názvosloví popsal vlastními slovy. Důvodem je to, že při tak ohromném množství nových výrazů nejsem schopen se ihned orientovat. Také jsem ovšem danou problematiku nepsal stylem step-by-step. Zde by se jednalo o neštastné řešení, zejména ve chvíli, kdy se jedná o rozsáhlejší problematiku. Zde bych doporučil použít metodiku (pokus/omyl) :) Jinými slovy, bez přemýšlení není člověk schopen pochopit daný úkol.

Příště se podívám na JPA a FetchType. K čemu slouží LAZY a EAGER. A jak je to vlastně s defaultní hodnotou mimo a uvnitř glassfishe.

pátek 20. dubna 2007

Java EE 5 - začátky aneb konec PHP

Každý, kdo začně blíže studovat Java EE5, získá celkový přehled o tom, jak je Java rozdělena do několika vstev. Společně s tím, ale vyvstane spoustu otázek, jak provést to či ono. Některé věci totiž nejsou úplně zřejmé a pokud chci tvořit projekt, který bude provázán s dalšími vrstvami, dostanu se dost často do potíží s nastavením a vůbec spuštěním jednotlivých částí.

Na začátku je důležité si zvolit správnou technologii. Pokud zvolím Javu budu muset řešit další věc a tou je její ohromné množství frameworků. Osobně jsem toto vyřešil tak, že se držím (pokud je to jen možné) standardů SUNu.

Takže co je cílem: Vytvořit intranetovou aplikaci, která bude pokrývat požadavky firmy. Od výrobních procesů, přes ekonomické záležitosti až po různé schvalovací procesy. Klientem bude webová či desktopová aplikace. Ve chvíli, kdy potřebuji komunikovat se sériovým portem, musím volit desktop. Když budu řešit výpis sestav, použiji zase webovou aplikaci. Obě tyto aplikace musejí míti stejnou základnu (databázi). V lepším případě základnou bude business logika pro obě aplikace.

Jak jsem psal výše, zvolil jsem nejpoužívanější frameworky, které jsou navíc i standardy. Na persistenci (připojení k databázi) TopLink od Oracle. Jako databázi MySQL 5.0. Na namapování relačních tabulek do objektů JPA. Samotná business logika je řešena přes EJB3.0. Na webovou část jsem zvolil JSF společně s Facelets (i když Facelets není standard, dost pomáhá samotnému JSF). Na desktop Swing. Aplikační server je Sun Java Application Server 9 (glassfish).

Takže zvolené součásti mám úspěšně za sebou. Nyní přistoupím k samotné implementaci. První věcí, kterou musím udělat, je rozjet MySQL v glassfish. Toto udělám jednoduše tak, že nahraji java-mysql-connector do adresáře PATH_GLASSFISH/lib. V samotné admin konsoli (webová aplikace pro správu glassfishe), vytvořím connection pool a jdbc resource pro mysql a danou databázi.

Nyní přistoupím k tvorbě business logiky. Po vytvoření enterprise projektu ptovedu vytvoření persistence pomocí TopLinku. Po namapování glassfishe do IDE, vytvořím persistence.xml, který volá pomocí JNDI spojení s MySQL, kterou jsem v glassfish konsoli vytvořil.

Pro namapování relačních tabulek do JPA využiji požnosti IDE a nechám si je automaticky vygenerovat. Pro snadou správu samotných dat, vytvořím na klientovi nějakou CRUD aplikaci, takže si nechám vygenerovat i Session Beans z JPA. Použiji jak lokální, tak remote interface. Po tomto kroku, mám základ připraven. Mohu provést deploy na glassfish.

Nyní se pustím do samotného klienta. Nejprve desktopu. Vytvořím si samostatný projekt, do kterého nalinkuji potřebné glassfish knihovny a přilinkuji samotnou business logiku ve formě jar souboru. Pomocí vzdáleného volání, si nechám zavolat Session Beanu a již rovnou mohu pracovat s business logikou ve Swingu. K samotné distribuci swingové aplikace použiji Java Web Start.

Poslední věcí je webová aplikace. Přilinkuji JSF Framework, společně s Facelets. V Backing Beans volám Local EJB. Webová aplikace je v tomto ohledu o dost jednodušší, jelikož nemusím řešit vzdálené volání EJB, protože samotná aplikace běží na glassfish ve webovém kontejneru. Samozřejmě nezapomenu na convertery pro Entity a nastavení, jako navigaci, atd. Webovou aplikaci mohu vystavit na server.

Asi takto bych zjednodušeně popsal samotnou problematiku Enterprise Javy. Jako IDE jsem zvolil NetBeans a k deploymentu aplikací chytrého mravence (ant).

Tímto článkem jsem chtěl jen nastínit, že s PHP končím. Od dnešní doby se budu věnovat Javě či databázím. Pokud je někdo v podobné situaci jako já, přivítám jeho připomínky.


Příště se již budu věnovat něčemu přímočarému. Ukážu, jak ve stand-alone klientovi volat EJB z glassfishe. Na konci celý projekt zbuilduji a nechám poskytovat pomocí Java Web Start.

čtvrtek 12. dubna 2007

PDT a OOP

Každý, kdo chce efektivně pracovat s objekty, musí použít nástroj, který mu umožní automaticky doplňovat potřebné informace. Jinými slovy, použije nějaké IDE, které usnadní práci při psaní kódu.

Když si představím, že vytvořím objekt, který obsahuje několik metod, rád bych tyto metody rovnou volal. U jazyků, které dodržují striktně typovou kontrolu, je to jednoduché. Každý parametr metody musí mít typové označení, stejně tak návratová hodnota. U PHP je situace o dost horší. Jediné, co mi samotné PHP umožňuje je, že u parametru metody mohu definovat o jaký typ objektu se jedná. Navíc jsem omezen pouze na objekty a pole.
Jenže metody mi často vrací další objekty a tyto objekty někde dál používám. Samotný plugin od ZENDu (PHP Development Tool = PDT) na to jde od lesa. Dovolí mi používat komentáře, ve kterých si jasně definuji, o jaký typ se vlastně jedná. Lepší než další povídání bude ukázka.

class TridaA {
public function foo() {}
}
class TridaB {
private $tridaA;
public function __construct() {
$this->tridaA = new TridaA();
}
public function zavolejFoo() {
$this->tridaA->foo();
}
}


Z ukázky je jasné, že atribut třídy B je vlastně objekt z třídy A. Eclipse mi sice umožní automaticky zavolat metodu foo();, ale pouze v konstruktoru, protože dál už nevidí. V metodě zavolejFoo(); mám prostě smůlu. Mám ale možnost samotný atribut třídy okomentovat, čímž vyjádřím, že se jedná o objekt třídy A a pak již vše funguje, jak má.


/**
* @var TridaA
*/
private $tridaA;


Další věcí budiž parametry metody. Na začátku jsem psal, že PHP sice dovoluje definovat typ pro parametr metody, ale ne vždy tak činíme. Pokud typovou kontrolu na parametr metody definovat nechci, ale chci, aby Eclipse poznalo, že se jedná o tu či onu instanci objektu, jednoduše metodu okomentuji.


/**
* @param TridaA $tridaA
*/
public function setTridaA($tridaA) {
$tridaA->foo();
}


U definování samotného parametru metody je třeba mít na paměti, že musím také definovat, o jaký parametr se vlastně jedná.

Poslední věcí je návratová hodnota metod. K tomuto mohu opět použít komentář a říci tak Eclipse, o jaký návratový typ se vlastně jedná.


/**
* @return TridaA
*/
public function getTridaA() {
return new TridaA();
}


Pokud tedy pracujete s objekty a používáte k tomu jazyk, který má dynamické typování, jistě Vás často naštve, že nevíte, co vlastně v danou chvíli proměnná obsahuje. Toto Vám sice nezaručí, že nebudete chybovat při zjišťování typů, ale zaručí, že samotné programovací prostředí Vám řekne, co teď vlastně používáte.

Jestli jste neměli v oblibě komentáře, tak nyní si je určitě zamilujete :)

O psaní komentářů by se dala napsat celá kniha, ale o tom zase jindy.

středa 4. dubna 2007

JSF & Facelets

Samotné JavaServer Faces (JSF) je ve své podstatě jednoduchý framework na view vrstvu, který komunikuje pomocí Backing Beans. JSF v žádném případě neruší metodiky JSP-Servletů, pouze je potlačuje ve prospěch vývojářů a snaží se nabídnout alternativu pomocí JSF.

V JSF je několik vlastností (zejména uvnitř faces-config.xml), které jistě stojí za to prozkoumat:

  • Navigace

  • Lokalizace a vlastní definice messages

  • Definice managed-beans (request, session) ...

  • Psaní HTML komponent v pomocí jsf/html

  • Tvorba vlastních UI komponent



Pro vývojáře, kteří mají s podobnými typy frameworků již zkušenosti, jistě není problém se JSF doučit. Ve chvíli, kdy je pro Vás jsp-servlet nový pojem, doporučuji rovnou začít na JSF. Samotná metodika Vás nakonec stejně donutí se jsp-servlety částečně doučit.

Když to vezmu do důsledků, tak jako vývojář v PHP jsem měl k jakýmkoliv frameworkům odpor. Ne snad z toho důvodu, že bych si raději všechno psal sám, ale z toho důvodu, že jsem nikdy nevěřil, že ten či onen framework bude i nadále podporován a že mi poskytne komplexní řešení.
U JSF je situace jiná. Samotný framework (stejně jako např. JavaPersistence API), je standardem SUNu, což samo o sobě dává pocit jakési jistoty, že se samotné API neučím nadarmo. Mám jistou záruku, že bude více využíván, dále podporován, či na něm budou postaveny další implementace, které se budou snažit dodržet standard a k tomu použiji své vlastní rozšíření.
Takovouto podobnost mohu nalézt např. mezi JPA a Hibernate, kde Hibernate se stalo plně kompatibilní s JPA a navíc nabízí vlastní rozšíření (např. CriteriaAPI).

Abych jen neházel samou chválou, přece jen mně na JSF trochu vadila jedna věc a to je "šablonovací systém". Nebo chcete-li, možnost, kdy budu vkládat své stránky do stejné "formičky".

Nakonec jsem našel "Facelets", což je v podstatě rozšíření samotného JSF, které je ovšem zaměřeno právě na šablonovací systém. Samotný popis lze nalézt zde.
Pro NetBeans existuje i vlastní plugin, který je popsán zde.

Takže pokud někdo začíná s webovými aplikacemi v Jave, doporučuji JSF-EJB3-JPA. I když není Java EE 5 zrovna jednoduchá záležitost (alespoň pro mě), tak stojí za to alespoň nahlédnout, jak vlastně taková architektura vícevrstvé aplikace (z pohledu Javy), vypadá.

Na webu Jakuba Vrány o PHP, se někteří lidé domnívali, že URL v JSF je statická. Na malý problém existuje malá náplast a tou je "" v navigation-case. Stejnou fintu je třeba použít, pokud budu tvořit zabezpečenou aplikaci přes url-pattern (/secure/*) v security-constraint.

úterý 27. března 2007

OOP v PHP5 díl.6 - viditelnost a klíčová slova

Pokud budeme mluvit o objektech jako o zapouzdřených componentách, musíme nějakým způsobem zajistit, aby daná komponenta poskytovala jen to, co skutečně má. Pokud bychom ignorovali viditelnost jako takovou, vznikl by nám mezi jednotlivými třídami chaos, který by zapříčinil nepoužitelnost.

Vezmu to pěkne od začátku, mám atributy třídy a metody třídy. Obě tyto vlastnosti každého objektu mají volitelnou viditelnost, která je rozdělena do tří úrovní:

  • public

  • protected

  • private



Public
Jakákoli vlastnost objektu nastavená viditelností public mi umožňuje říci, že: "každý má právo k této vlastnosti přistupovat".

Protected
Narozdíl od public, má protected omezení jen na viditelnost v samotné třídě a třídách, které jsou potomkem.

Private
K vlastnostem označeným jako private může přistupovat pouze a jedině vlastní třída.

Když jsem v minulých dílech tvrdil, že atributy třídy by měly být označeny vždy jako private, neříkal jsem úplně pravdu. Při tvorbě vlastních tříd se dost často setkáme s problémem, kdy bych potřeboval použít daný atribut jako parametr metody. Jinými slovy řečeno, podle parametru mi metoda vykoná to či ono.

class HTML_Form_Input {
private $value;
.....
public function __construct($value) {
$this->value = $value;
}

public function setValue($value) {
$this->value = $value;
}

public function getValue() {
return $this->value;
}
.....
}


Tato jednoduchá třída implementovala private jako viditelnost pro atribut třídy a public jako atribut pro konstruktor a setry a getry. Teď ovšem nastává problem, kdy bych potřeboval identifikovat typ samotného inputu. Jedna z možností by byla, že bych metodě setType(String) vždy posílal vlastním stringem, o jaký typ se vlastně jedná. Toto sice lze, ale my se budeme snažit o co nejlepší znovupoužitelnost a možnost nastavení těchto typů přímo ve třídě, abychom nemuseli při refactoringu dohledávat všechny různé překlepy, atd.

class HTML_Form_Input {
const TYPE_HIDDEN = "hidden";
....
}
$input = new HTML_Form_Input("jmeno");
$input->setType(HTML_Input_Form::TYPE_HIDDEN);


Konstanta jako taková je neměná a je přístupná mimo vytvořený objekt. Pokud bych chtěl danou konstantu volat přímo ve třídě, využiji k tomu self::.

S dalším klíčovým slovem, se kterým se můžete setkat, je static. Statický atribut či metoda je taková vlastnost, která mi zapříčiní, že ji mohu získat aniž bych musel vytvářet objekt. Její hodnota je tedy nezávislá na tom, zda objekt existuje či nikoli. Pokud bych to převedl do praxe, můžu pomocí statického atributu třídy zjišťovat, kolikrát jsem vytvořil objekt z dané třídy.

Další ukázky si nechám do příštího dílu, který budu věnovat Design Patterns, neboli návrhovým vzorům. Ukážu např. implementování Iteratoru, který lze nativně v PHP 5 nalézt.

pondělí 19. března 2007

PHP & Java: SHA-1

Při vývoji javovské aplikace jsem narazil na problém autentifikace uživatelů. Problém spočíval v tom, že mám tabulku uživatelů, která obsahuje hash hesla, který je hashován pomocí PHP.

echo sha1(sha1("heslo"));


Čekal jsem, že v Java API naleznu podobnou metodu na hash Stringu, bohužel jsem hledal marně :)

Jelikož jsem si nevěděl rady, poprosil jsem na konferenci na java.cz o malou pomoc. Po odpovědi obsahující link, na tvorbu hashe ze Stringu, jsem moc moudrý nebyl :(
Potom jsem dostal ovšem odpověď v podobě třídy, kterou jsem nakonec po své úpravě byl schopen aplikovat.

package org.dostal.dochazka.crypt;

import java.security.MessageDigest;
/**
* Statické metody pro výpočet hash
*
* @author Ales Dostal;
*/
public class HashUtil {

public static final String HASH_TYPE = "SHA-1";

/**
* konstruktor
*/
private HashUtil() {}

/**
* vypocita SHA-1 hashovaci klic z byte[] a vrati jej jako HEXa retezec
*
* @param pass heslo ve String
* @return HEXa řetězec
*/
public static String SHA1AsString(String pass) {
return SHA1AsString(pass.getBytes());
}

/**
* vypocita SHA-1 hashovaci klic z byte[] a vrati jej jako HEXa retezec
*
* @param pass heslo v byte[]
* @return HEXa retezec
*/
public static String SHA1AsString(byte[] pass) {
return hex(SHA1(pass));
}

/**
* vypocita SHA-1 hashovaci klic z char[] a vrati jej jako HEXa retezec
*
* @param pass heslo v char[]
* @return HEXa retezec
*/
public static String SHA1AsString(char[] pass) {
return SHA1AsString(String.valueOf(pass));
}

/**
* Vypočte SHA-1 hashovací klíč z řetězce
*
* @param secret pomocný klíč
* @return pole bytů
*/
private static byte[] SHA1(byte[] pass) {
byte[] mac = new byte[20];
try {
MessageDigest sha = MessageDigest.getInstance(HASH_TYPE);
sha.update(pass);
mac = sha.digest();
} catch (Exception e) {
e.printStackTrace();
}
return mac;
}

/**
* Převede pole bytů na HEXa řetězec.
*
* @param data pole bytů
*/
private static String hex(byte[] data) {
StringBuilder sb = new StringBuilder();
for (byte b : data) {
sb.append(Character.forDigit((b & 240) >> 4, 16));
sb.append(Character.forDigit((b & 15), 16));
}
return sb.toString();
}

}


Nyní jsem schopen přistupovat k porovnání hashe jak z PHP, tak z Javy. Sice je to taková maličkost, ale občas dost důležitá :)

echo sha1("heslo");

System.out.println(HashUtil.SHA1AsString("heslo"));

úterý 6. března 2007

OOP v PHP 5 - teorie dědičnosti a ORM

Když se vrátím na začátek, kde jsem tvrdil, že objekty jsou jakýsi obal nad procedurálním kódem, tak se musím zamyslet nad tím, jak umožnit, abych nemusel stále dokola zabalovat jednu a tu samou věc. Třídy bych měl vždy navrhovat tak, aby obsahovali jen to nejnutnější a nebyly zbytečně vázany na jiné třídy. Navíc třídy by něměli obsahovat pevnou vazbu na třídy, které jsou navrženy v jiných úrovních.

Příklad:
Do třídy pro zobrazení stromové struktury nebudu cpát třídu, která mi vrací data stromu. Raději ve třídě stromu napíši metodu, která bude umět přijmout data a zobrazit je. Na získání dat vytvořím jinou třídu.
Když budu později potřebovat zobrazit strom s jinými daty, prostě použiji již hotovou třídu stromu, která přijímá data.


Tím dokážu vytvořit znovupoužitelný kód. K tomu, abych mohl takto tvořit třídy, ale musím znát všechny možnosti objektů. Nyní se vratím k další možnosti objektů a tou je dědičnost.

Dědičnost je vlastnost, která mi umožňuje rozšířit třídu a pozměnit její chování. Nic víc, nic míň.

Na začátku jsem napsal, že třídy by měli být co nejořezanější, neměli by obsahovat věci, které by ji svázali natolik, že by obsahovala zbytečné a nevyužitelné vazby. Pokud ovšem v projektu potřebuji danou třídu rozšířít a to tak, že dané rozšíření budu využívat vícekrát, prostě napíši si novou vlastní třídu, která bude dědit vlastnosti z minulé třídy.

Příklad:
Mám třídu na zobrazování filtrace nad daty. Teď je ovšem problém, že v některých případech filtruji přes ty samé položky (př. název). Jednou možností je, pořád do objektu posílat objekt (komponentu) název. Jelikož už vím, co je dědičnost, mohu ji využít. Vytvořím novou třídu, která bude dědit třídu filtrace a navíc bude automaticky vkládat komponentu pro název.


Toto je jedna z možností jak dědičnost využít, přiznávám, že ne moc efektivní, jistě existují i jiné možnosti, ale jako příklad je to postačující.

Asi lepším příkladem je struktura dat v databázi. Dnes jsou nejrozšířenejší relační typy databází. Jistě jsou velmi efektivní, rychlé a snadné na práci, ale pro nás jsou dost nevyhovující, proto existuje ORM (objektově relační mapování), což není nic jiného, než, že tabulku v databázi převedeme na objekt.

CREATE TABLE zamestnanec (
cislo int NOT NULL,
jmeno varchar(100) NOT NULL,
prijmeni varchar(100) NOT NULL,
PRIMARY KEY(cislo)
);



class Zamestnanec {
private $cislo;
private $jmeno;
private $prijmeni;
/* + setry a getry ke vsem atributum */
}


Nyní vytvoříme tabulku "uzivatele". U uživatelů budeme potřebovat navíc heslo, počet přihlášení, poslední přihlášení. V databázi tedy vytvoříme tabulku "uzivatele", která bude mít primární klíč osobní číslo, které bude zároveň cizím klíčem s vazbou do tabulky zaměstnanců na osobní číslo.

Potom pro výpis uživatelů použijeme něco takového:
SELECT u.*, z.jmeno, z.prijmeni
FROM uzivatele u
INNER JOIN zamestnanci z ON u.cislo = z.cislo


To je v pořádku, databázi máme, ale jak to uděláme v našem projektu, kde máme objekty? Velice jednoduše, použijeme dědičnost.

class Uzivatel extends Zamestnanec {
private $heslo;
private $pocetPrihlaseni;
private $posledniPrihlaseni;
/* setry a getry */
}


Nyní jsem vlastně rozšířil zamestnance o další atributy aniž bych musel znovu psát jeho vlastnosti (např. v Jave na toto existují tzv. entity classes, u nich by bylo toto rozdělení více podobné struktuře DB, což v PHP zařídit jen tak nepůjde). Dědičnost se definuje tak, že mám jednoho předka, který obsahuje vlastnosti, které se mi budou hodit i ve třídě, která je dědí. Pokud by se mi stalo to, že budu dědit z třídy, která obsahuje vlastnosti, které nebudu nikdy potřebovat, je dědičnost navržena špatně.

Tento článek berte spíše s nadhledem, opravdu se domnívám, že dědičnost je tak záludná záležitost, že bych se na ni na začátku úplně vykašlal. V pozdějších článcích se k tomto tématu vrátím a ukážu, jak něco takového využít v praxi. Příklady, které jsem zde uvedl nejsou úplně nejtypičtější, ale jistě lepší, než ukázky typu: Matka => Dcera, které postrádají použitelnost v praxi.

Příště už o něčem jednoduchém, viditelnosti a klíčových slovech static, final, apod.

Když programátor založí a řídí firmu

Jako malý jsem chtěl být popelářem. Ani ne tak proto, že bych měl nějaký zvláštní vztah k odpadkům, ale hrozně se mi líbilo, jak...