<p>Nagyon jo osszefoglalo, a pelda rossz egyedul.</p>
<p>Mert mi is tortent? Valamiert nem tudtunk olvasni. Ilyenkor ketfelekepp lehet tovabbmenni:<br>
 - processzaljuk ami van, aztan jelzunk, hogy nincs tovabb<br>
 - nincs eleg adat, dobunk egy kivetelt, amibe belerakjuk az ioexception-t.</p>
<p>Kesz, az alkalmazasnak ennyi a feladata. Barmi varatlan is tortent, az alkalmazasnak nem feladata belemenni egy barchobaba, hogy mi. Unexpected error occurred. Az IOException mar ajandek.</p>
<p>Az exception-os readLine vhogy ugy nezne ki, h:</p>
<p>while(r.ready()) <br>
  lines.append(r.readLine());</p>
<p>Persze ez pszeudokod. Ilyenkor nincs exception mert a ready() ellenorzi, h van-e meg mit olvasni. </p>
<p>A lines.append kore lehet try/catch cuccokat dobni, ha hianyos adatot is lehet processzalni (pl. minden sikeresen beolvasott sor egy komplett parancs, amit fel lehet dolgozni), vagy a while kore ha hibanal le kell allni. De hiba csak akkor lehet, ha pont a ready() es a readLine() kozott tortenik vmi. Es (mivel ez pufferelt olvasas) csak buffer underrunnal.</p>

<p>Udv,<br>
Garami Gábor<br>
<a href="mailto:gabor.garami@hron.me">gabor.garami@hron.me</a><br>
Skype: hron84<br>
Tel: +36 20 235 9621</p>
<p>Sent from my T-Mobile G2<br>
Ezt a levelet telefonról adták fel, ékezethibákat tartalmazhat.</p>
<div class="gmail_quote">2012.07.24. 23:26, &quot;Peter Verhas&quot; &lt;<a href="mailto:peter@verhas.com">peter@verhas.com</a>&gt; ezt írta:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div style="word-wrap:break-word">Mitől lesz jó egy pattern? Ezek a saját gondolataim:<div><br></div><div>1. A legfontosabb, hogy a pattern alapján készült programok működnek, azaz maga a pattern, mint tervezési minta nem hibás. Ez alapvető.</div>
<div><br></div><div>2. Majdnem ilyen fontos, hogy a pattern alapján készült programoknak csak az elenyésző része legyen hibás azon okból kifolyólag, mert rosszul implementálták a patternt. Ha ugyanis van egy olyan pattern-em, ami megfelel az 1-es kritériumnak, de olyan bonyolult, vagy kacifántos, hogy az átlag programozó észre sem veszi, hogy mikor tért el tőle a megvalósítás során, vagy azt nem veszi észre, hogy olyan problémánál használja, amikor az nem megfelelő, mint pattern, akkor azt a pattern-t el kell felejteni, nem tölti be a feladatát.</div>
<div><br></div><div>3. A pattern alapján készülő kódok legyenek hatékonyak, azaz a szükségesnél lényegesen több memóriát, processzor időt, futási időt, és egyéb erőforrásokat ne használjanak. Ez persze a kódolástól is függ, de ha a tipikus kódolási hibákra rá- vagy éppen megvezet egy pattern, akkor az a pattern nem jó.</div>
<div><br></div><div>4. A pattern alapján készülő kódok legyenek karbantarthatóak, azaz egyszerű legyen őket olvasni. Ez persze megint olyan, hogy nem csak a patterntől függ, de a pattern maga ezt nagyban tudja rossz irányba terelni ha maga a pattern nem megfelelő.</div>
<div><br></div><div>5. A pattern alapján készülő kódok legyenek olyanok, hogy hatékony végrehajtható kódot lehessen belőlük fordítani. Ez nem ugyanaz, mint a 3. pont. Ott elsősorban az algoritmikus hatékonyságra kell gondolni, míg itt optimalizációra. Tipikusan ha egy pattern buborék rendezést ír le egy rendezési feladatra (ami a pattern része), azt már optimalizálhatja a fordító amennyit akarja, nem lesz belőle hatékony kód. Ez a 3. pont. Ugyanakkor olyan kódolási pattern-ek, mint felesleges átmeneti változók használata, és hasonlók komoly hatással lehetnek a generált kód sebességére, amennyiben nem áll rendelkezésre egy megfelelően hatékony optimalizáló fordító. A Java esetében rendelkezésre áll, ezért ezt az 5. pontot gyakorlatilag epsilon fontossággal tekinthetjük.</div>
<div><br></div><div>Az, hogy null értéket adunk-e vissza, vagy exception-t dobunk valamilyen tervezési minta szerint igazán a 4. pontot érinti.</div><div><br></div><div>Technológiai okok miatt C++ és C# (általánosan .NET) környezetben nem szeretünk exception-t dobni (én magam programozni sem szeretek ezekben a környezetekben, nem is tudok (nagyon), hát még kivételt dobni). Ezekben a környezetekben a kivétel dobása drága, egészen más a kivételek szerkezete, és ezért nem is ad megfelelő információt. Tipikusan nincs benne a stack trace, ezért ha egy szinttel feljebb, mint ahonnan dobták nem kapjuk el, akkor már nem is lehet tudni, hogy honnan dobták. Akkor meg már olcsóbb futási időben a megfelelő hibakód visszaadása, és ennek nagy hagyománya van unix C és Windows C programozási környezetben, régen bevált. [Megjegyzés: ennek a bekezdésnek az egyik fele nem első kézből való információ, csak beszélgettem .NET-es kollégákkal. A másik fele viszont ezer évvel ezelőtti C programozási emlékek megmaradt halvány foszlányai.]</div>
<div><br></div><div>A Java egészen más. Java-ban az exception hordozza a stack trace-t (vagy nem, de inkább igen, mint nem), és ebben nagyon sok szimbolikus információ benne van. Nem kell ott elkapni, ahol dobják, vagy egy szinttel feljebb, mert minden szükséges információ benne van, és ezért elég ha ott kapjuk el, ahol kezelni tudjuk. Ezért lett egyébként kitalálva a hiba dobás, és véleményem szerint a .NET környezet az exception dobás, mint pattern funkcionalitásának egy részét feláldozta a teljesítmény oltárán, amit viszont mostanra (Java6, 7) kezd túlhaladni az idő.</div>
<div><br></div><div>Ezután a bevezető után próbáljuk meg eldönteni, hogy melyik a jobb pattern: null-t visszaadni, vagy kivételt dobni egy speciális helyzetben. Nézzük meg a következő kis kódot:</div><div><br></div><div><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco">
<span style="white-space:pre-wrap">                </span>BufferedReader r = <span style="color:#9c0767">new</span> BufferedReader(<span style="color:#9c0767">new</span> InputStreamReader(</div><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco">
<span style="white-space:pre-wrap">                                </span><span style="color:#9c0767">new</span> FileInputStream(file)));</div><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco">
<span style="white-space:pre-wrap">                </span>String line = <span style="color:#9c0767">null</span>;</div><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco">
<span style="white-space:pre-wrap">                </span><span style="color:#9c0767">while</span> ((line = r.readLine()) != <span style="color:#9c0767">null</span>) {</div><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco">
<span style="white-space:pre-wrap">                        </span>System.<span style="color:#0f25c7">out</span>.println(line);</div><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco">
<span style="white-space:pre-wrap">                </span>}</div></div><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco"><font face="Verdana"><br></font></div><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco">
<font face="Verdana">Aránylag egyszerű, tiszta és világos kód, bár a &#39;while&#39; feltételben az értékadás egy kicsit C örökség, és nem a Java szokásos stílusa. Hogyan nézne ki ez a kód akkor, ha a &#39;readLine&#39; nem null-t adna vissza a fájl végén, hanem kivételt dobna:</font></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco"><font face="Verdana"><br></font></div><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco">
<font face="Verdana"><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco"><span style="white-space:pre-wrap">                </span><span style="color:#9c0767">try</span> {</div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco"><span style="white-space:pre-wrap">                        </span><span style="color:#9c0767">while</span> ((line = r.readLine()) != <span style="color:#9c0767">null</span>) {</div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco"><span style="white-space:pre-wrap">                                </span>System.<span style="color:#0f25c7">out</span>.println(line);</div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco"><span style="white-space:pre-wrap">                        </span>}</div><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco">
<span style="white-space:pre-wrap">                </span>} <span style="color:#9c0767">catch</span> (IOException e) {</div><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco;color:rgb(61,145,115)">
<span style="color:#000000"><span style="white-space:pre-wrap">                        </span></span>// and now what?</div><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco">
<span style="white-space:pre-wrap">                        </span>e.printStackTrace();</div><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco"><span style="white-space:pre-wrap">                </span>}</div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco"><br></div><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco">
<font face="Verdana">első ránézésre nem világos, hogy mit kell keresnünk a catch ágban. Kihúzták az USB diszket, amit olvastunk vagy véget ért a fájl. Ez el kell döntenünk az IOException alapján. Mondjuk lehetne így:</font></div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco"><font face="Verdana"><br></font></div><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco">
<font face="Verdana"><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco"><span style="white-space:pre-wrap">                </span><span style="color:#9c0767">try</span> {</div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco"><span style="white-space:pre-wrap">                        </span><span style="color:#9c0767">while</span> ((line = r.readLine()) != <span style="color:#9c0767">null</span>) {</div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco"><span style="white-space:pre-wrap">                                </span>System.<span style="color:#0f25c7">out</span>.println(line);</div>
<div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco"><span style="white-space:pre-wrap">                        </span>}</div><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco">
<span style="white-space:pre-wrap">                </span>} <span style="color:#9c0767">catch</span> (EOFException e) {</div><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco;color:rgb(61,145,115)">
<span style="color:#000000"><span style="white-space:pre-wrap">                        </span></span>// unexpected?</div><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco">
<span style="white-space:pre-wrap">                </span>} <span style="color:#9c0767">catch</span> (IOException e) {</div><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco;color:rgb(61,145,115)">
<span style="color:#000000"><span style="white-space:pre-wrap">                        </span></span>// and now what?</div><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco">
<span style="white-space:pre-wrap">                        </span>e.printStackTrace();</div><div style="margin-top:0px;margin-right:0px;margin-bottom:0px;margin-left:0px;font:normal normal normal 11px/normal Monaco"><span style="white-space:pre-wrap">                </span>}</div>
</font></div></font></div><div><br></div><div>Viszont az EOFException dokumentációja szerint ezt akkor kell dobni, amikor váratlanul értük el a fájl végét. Itt pedig nagyon is vártuk, azért tettük bele egy &#39;while&#39; ciklusba. Ez így jóval kevésbé olvasható.</div>
<div><br></div><div>Ezért a konkrét pattern ismerete nélkül én nem mondanám, hogy a null visszatérési érték rossz pattern. Vagy rossz, vagy nem.</div><div><br><div>
<div style="word-wrap:break-word;font-family:Helvetica"><div style="word-wrap:break-word"><div><span style="color:rgb(136,136,136)">--</span><span style="color:rgb(136,136,136)"><br></span><span style="color:rgb(136,136,136)">Verhás Péter</span><span style="color:rgb(136,136,136)"><br>
</span><span style="color:rgb(136,136,136)"></span><span style="color:rgb(136,136,136)"><a href="mailto:peter@verhas.com" target="_blank">peter@verhas.com</a></span><span style="color:rgb(136,136,136)"><br></span><span style="color:rgb(136,136,136)"><a href="tel:%2B36%2830%299306805" value="+36309306805" target="_blank">+36(30)9306805</a></span><span style="color:rgb(136,136,136)"><br>
</span><span style="color:rgb(136,136,136)">skype: verhas</span></div></div><br></div><br><br>
</div>
<br><div><div>On 2012.07.24., at 9:38, Gábor Garami wrote:</div><br><blockquote type="cite"><div>Nyilvan. Ettol meg rossz pattern lesz a null visszateres, csak vannak<br>olyan jol definialt interfacek, amik rossz pattern menten szulettek.<br>
<br>Garami Gábor<br>E-mail: <a href="mailto:gabor.garami@hron.me" target="_blank">gabor.garami@hron.me</a><br>Tel: <a href="tel:%2B36%2020%20235%209621" value="+36202359621" target="_blank">+36 20 235 9621</a><br>MSN: <a href="mailto:hrgy@vipmail.hu" target="_blank">hrgy@vipmail.hu</a><br>
Skype: hron84<br><br><br>2012/7/23 Peter Verhas &lt;<a href="mailto:peter@verhas.com" target="_blank">peter@verhas.com</a>&gt;:<br><blockquote type="cite">Azért a való életben az is előfordul, hogy nem te szabod meg, hogy a metódus<br>
</blockquote><blockquote type="cite">mikor dob kivételt, és mikor tér vissza null értékkel. Ezzel nem mondok<br></blockquote><blockquote type="cite">neked ellent, csak van olyan, amikor egy jól definiált interface-t<br></blockquote>
<blockquote type="cite">valósítasz meg.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">--<br></blockquote><blockquote type="cite">Verhás Péter<br></blockquote><blockquote type="cite"><a href="mailto:peter@verhas.com" target="_blank">peter@verhas.com</a><br>
</blockquote><blockquote type="cite"><a href="tel:%2B36%2830%299306805" value="+36309306805" target="_blank">+36(30)9306805</a><br></blockquote><blockquote type="cite">skype: verhas</blockquote></div></blockquote></div><br>
</div></div><br>_______________________________________________<br>
Javalist mailing list<br>
<a href="mailto:Javalist@lists.javaforum.hu">Javalist@lists.javaforum.hu</a><br>
<a href="http://lists.javaforum.hu/mailman/listinfo/javalist" target="_blank">http://lists.javaforum.hu/mailman/listinfo/javalist</a><br>
<br></blockquote></div>