<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>GhoUl &#187; Post Tags &#187; tervezés</title>
	<atom:link href="http://cubussapiens.hu/tag/tervezes/feed/" rel="self" type="application/rss+xml" />
	<link>http://cubussapiens.hu</link>
	<description>A Cubus Sapiens oldal</description>
	<lastBuildDate>Thu, 19 Aug 2010 19:17:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>OpenOffice egér &#8211; avagy hogyan ne&#8230;</title>
		<link>http://cubussapiens.hu/2009/11/openoffice-eger-avagy-hogyan-ne/</link>
		<comments>http://cubussapiens.hu/2009/11/openoffice-eger-avagy-hogyan-ne/#comments</comments>
		<pubDate>Sun, 22 Nov 2009 23:06:05 +0000</pubDate>
		<dc:creator>Stampie</dc:creator>
				<category><![CDATA[A mi gépünk]]></category>
		<category><![CDATA[tervezés]]></category>
		<category><![CDATA[usability]]></category>

		<guid isPermaLink="false">http://cubussapiens.hu/?p=1295</guid>
		<description><![CDATA[Kicsit megkésve (november 6-án már olvastam a dologról, csak azóta nem igazán volt időm/energiám erre is reagálni) szeretnék megemlékezni az OOMouse nevű csodáról. Ez, mint a neve is mutatja, egy egér, és az OpenOffice csomaghoz van köze. Először is szeretném leszögezni, hogy nem az OpenOffice fejlesztőinek munkája az egér, hanem az egeret készítő cég készített [...]]]></description>
			<content:encoded><![CDATA[<p>Kicsit megkésve (november 6-án már olvastam a dologról, csak azóta nem igazán volt időm/energiám erre is reagálni) szeretnék megemlékezni az <a href="http://openofficemouse.com/pr110609.html">OOMouse</a> nevű csodáról. Ez, mint a neve is mutatja, egy egér, és az OpenOffice csomaghoz van köze.</p>
<p>Először is szeretném leszögezni, hogy nem az OpenOffice fejlesztőinek munkája az egér, hanem az egeret készítő cég készített nyílt forrású, OpenOffice-t támogató drivert a cucchoz. Ezt azért éreztem fontosnak, mert ugyan az OpenOffice nem az ergonomikus szoftvertervezés csúcsa, de ez messze alulmúlja azt a szintet.</p>
<p>A leírás első körben bizalomgerjesztő: sok gomb (18), külön joystick az egéren, különböző módok, és mindez szoftveresen testreszabható.</p>
<p>Viszont ezután jött a fotó az egérről: a gombok az egér tetején helyezkednek el, rács mentén elhelyezve. Mi is ezzel a gondom?</p>
<div id="attachment_1296" class="wp-caption alignnone" style="width: 310px"><a href="http://cubussapiens.hu/wp-content/uploads/2009/11/OOmouse_model.png" rel="lightbox[1295]" rel="attachment wp-att-1296" title="Az OpenOffice egér"><img class="size-medium wp-image-1296" title="Az OpenOffice egér" src="http://cubussapiens.hu/wp-content/uploads/2009/11/OOmouse_model-300x295.png" alt="Egy egyszerű, fehér egér 18 gombbal, görgővel és joystickkel" width="300" height="295" /></a><p class="wp-caption-text">Egy egyszerű, fehér egér 18 gombbal, görgővel és joystickkel</p></div>
<p>Egyrészt a gombok mérete feltehetőleg viszonylag kicsi: a görgő két oldalán 3-3 oszlopnyi gomb van (és gyk. 3-3 sornyi is). Ha ennyi a gomb, akkor hogyan oldják meg, hogy nehéz legyen mellényúlni?</p>
<p>A másik fő problémám az, ami miatt a távirányítón is megszüntették a rács szervezést: ha sok a gomb, akkor jobb, ha a gyakran használt gombok egyedi formájúak, és nagyok, mert akkor anélkül tud a felhasználó választani, hogy odapillanata, merre van (igen, a billentyűzetek &#8220;f&#8221; és &#8220;j&#8221; gombjain levő jelzés &#8211; tipikusan kidomborodás vagy bemélyedés is erre való &#8211; ezek segítségével az ember tudja, hogy hol van az ujja).</p>
<p>Ha megnézzük, a joystick helye is érdekes: a hüvelykujjnál, egy gomb(!) mellett. Jó kérdés, hogy ez a kilógó elem mennyire piszkálja az ujjamat, amivel az egeret kell irányítanom, illetve mennyire könnyen tudom véletlenül megnyomni. A mellette levő gomb meg érzésre teljesen használhatatlan &#8211; nem férek hozzá.</p>
<p>Mielőtt valaki megvádolna, hogy Apple-fanként csak egygombos egérrel boldogulok, kijelentem, hogy volt dolgom többgombos egérrel &#8211; olyan 5-6 gombig. Alapvetően nem volt gondom vele, eltekintve attól, hogy a 4-5-6. gombokat nagyon ritkán sikerült kihasználni. A tapasztalatom az, hogy a bal gomb, jobb gomb, görgő (aminek lenyomása lehet a harmadik gomb) triónál többet nagyon kevés alkalmazás támogat, és viszonylag kellemetlen is használni. Az egyetlen, aminek látnám értelmét, az 1D mozgást leíró görgő helyett valami 2D-s eszközt betenni (mint az Apple Mighty Mouse eszközében a golyó &#8211; most már Magic Mouse).</p>
<p>És ami a legszebb, az ára: $74.99. Vezetékkel. Ezzel szemben az Apple új, vezeték nélküli, érintőfelületű egere $69. Amit szintén sokallok azért az egérért&#8230; De ez már az én egyéni, szociális problémám.</p>
<p>Amikor a múltkor <a href="http://cubussapiens.hu/2009/10/szamitogep-hasznalat-maskeppen/">felhasználói felületekről írtam</a>, akkor is hasonló mennyiségű kritikát írtam &#8211; de szemben azzal ez a kritika határozottan negatív.</p>
<p>Összességében: az egér elképesztően bonyolult. Sok gomb, sok  mód, sokféle operációs lehetőség. A szoftverét nem láttam, az lehet,  hogy a legkirályabb cucc a szeletelt kenyér óta, de a hardverről egy  képet látva nagyon nem bizakodom.</p>
<p>Körkérdés: kedves olvasók, ti látjátok értelmét ennek a 18 gombos egérnek?</p>]]></content:encoded>
			<wfw:commentRss>http://cubussapiens.hu/2009/11/openoffice-eger-avagy-hogyan-ne/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Fejlesztés, metodikák, ortogonális kódok</title>
		<link>http://cubussapiens.hu/2009/10/fejlesztes-metodikak-ortogonalis-kodok/</link>
		<comments>http://cubussapiens.hu/2009/10/fejlesztes-metodikak-ortogonalis-kodok/#comments</comments>
		<pubDate>Wed, 28 Oct 2009 21:10:11 +0000</pubDate>
		<dc:creator>Stampie</dc:creator>
				<category><![CDATA[Fejlesztés]]></category>
		<category><![CDATA[programozás]]></category>
		<category><![CDATA[tervezés]]></category>

		<guid isPermaLink="false">http://cubussapiens.hu/?p=1272</guid>
		<description><![CDATA[D-nee tett fel hétvégén egy érdekes linket a deliciousre: Jeremy D. Miller írt egy egész részletes szösszenetet Orthogonal Code címmel, és egész jól összefoglal bizonyos programtervezési elveket. Mondjuk ha csak annyi lenne a véleményem róla, hogy érdemes elolvasni, akkor egyszerűen fognám magam, és én is feltenném a deliciousre, hogy az a kevés ember, aki véletlenül [...]]]></description>
			<content:encoded><![CDATA[<p>D-nee tett fel hétvégén egy érdekes linket a deliciousre: Jeremy D. Miller írt egy egész részletes szösszenetet <a href="http://codebetter.com/blogs/jeremy.miller/archive/2007/01/08/Orthogonal-Code.aspx">Orthogonal Code</a> címmel, és egész jól összefoglal bizonyos programtervezési elveket.</p>
<p>Mondjuk ha csak annyi lenne a véleményem róla, hogy érdemes elolvasni, akkor egyszerűen fognám magam, és én is feltenném a deliciousre, hogy az a kevés ember, aki véletlenül odatéved, megtalálja. De a helyzet az, hogy egyfelől érdekesnek tartom, másrészt nem értek vele (mindenben) egyet.</p>
<p>Ami feltétlenül tetszett az írásban, és ami miatt minden, programozásban érintett embernek ajánlom elolvasásra, hogy konkrét példán bemutatja a különböző programfejlesztési elveket. Ráadásul mosóporreklám stílusban, azaz ilyen volt és ilyen lett összehasonlítással.</p>
<p>Előrebocsátanám még (egyszer), mielőtt elkezdek belemenni egyes részletkérdésekbe, hogy a cikkel alapvetően egyetértek, de néhány dolog érdemes továbbgondolásra. Az egyik, hogy ezeket a tervezési elveket szabálynak állítja be, szerintem viszont legfeljebb ökölszabálynak lehet tekinteni. Azaz alapvetően érdemes követni őket, kivéve, ha nem jók az adott helyzetben. <img src='http://cubussapiens.hu/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> </p>
<p>Miért lehetnek rosszak ezek az elvek? Például ha minden egyes funkciót külön osztályba teszünk, az osztályok, interfészek száma könnyen kezelhetetlen méretűre duzzadhat. Szóval amit megnyerünk a réven (áttekinthetőbbek és szerkeszthetőbbek a lokális kódok), elveszíthetjük a vámon (struktrurálisan nehezen áttekinthető a rendszer, nagy a betanulási idő).</p>
<p>Emellett a sok indirekció és absztrakciós szint teljesítményproblémákhoz vezethet. Például egy hívásnak nem elhanyagolható költségei vannak (stackelés, stb.). Vagy éppen hivatkozhatnék arra a nem túl régi tapasztalatomra, hogy egy algoritmusnál a legtöbb időt az vitte el, hogy a <strong>memóriából</strong> ismételten lekért adatokat. Ezt profilerrel derítettem ki, és lokális változóba áttöltve az adatokat és újra felhasználva kb. felére csökkentettem a futási időt. Vicces dolog az a cache miss (legalábbis szerintem ez történhetett).</p>
<p>És a legkomolyabb, kimutatható probléma (szerintem): a &#8220;tell, don&#8217;t ask&#8221; elvet jelenleg piszkosul nem szokás adatmodellre alkalmazni. Legalábbis Java környékén az aktuális state of the art marhára nem teszi &#8211; kivéve, ha rosszul látom, hogy mi a legfejlettebb. Aminek akár még oka is lehet.</p>
<p>A &#8220;tell, don&#8217;t ask&#8221; elv mit is jelent? Mondd meg az objektumnak, hogy mit csináljon (állapotfüggően), ne lekérd az állapotát, és ez alapján te döntsél helyette.</p>
<p>Érdekes módon viszont az adatmodellek manapság egyre inkább mennek a nagyon buta, csak getter/setterekből álló modellek felé. Miért is? Én úgy tippelem azért, mert</p>
<ol>
<li>Ez a rész jól generálható. Az EMF alaptechnológia tipikusan arról szól, hogy valahogy összeklikkelgetsz egy EMF modellt, beállítod a genmodellt, és kapsz egy gyönyörűséges Java osztályhalmazt. Ami persze nem tud semmit azon túl, hogy getter, setter és factory hívásokkal felépíthető és bejárható.</li>
<li>J2EE technológiánál az entitásokat menti le a rendszer egy az egyben adatbázisba, amely entitásoknak tipikusan szintén getter/setter metódusai vannak. Esetleg még számított mezők is beköszönnek.</li>
</ol>
<p>Mindkét esetben az a szokás, hogy a modellbefolyásoló logikát külön Manager jellegű osztályokba tesszük, akik a tényleges igényeknek megfelelően építik (rombolják <img src='http://cubussapiens.hu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ) a modellt.</p>
<p>És végül a legfontosabb hozzáfűznivalóm az íráshoz: igen, hosszú távon megéri ezeket az elveket követve tervezni, kivéve, ha amiatt, mert nem készülünk el határidőre, rövid/közepes távon befejeződik a projekt. És ennek a kezelése bizony emberi kérdés. Emiatt zárszóként <a href="http://www.codinghorror.com/blog/archives/001288.html">Jeff Atwoodot idézném</a>:</p>
<blockquote><p>The guys and gals who show up every day <a href="http://www.codinghorror.com/blog/archives/000856.html">eager to hone their craft</a>, who are passionate about building stuff that <em>matters</em> to them, and perhaps in some small way, to the rest of the world &#8212; those are the people and projects that will ultimately succeed.</p></blockquote>
<p>PS.: Mostanában <a href="http://www.adamnemeth.hu/2009/10/02/architect-dolgok-logika-es-struktura/">Aadaam</a> is foglalkozik azzal, hogyan <a href="http://www.adamnemeth.hu/2009/10/19/architect-dolgok-framework-napok-alatt/">érdemes nagyobb rendszereket összerakni</a>. Ráadásul azt mutatja meg, hogyan lehet PHP-ban nem gányolni. Szép teljesítmény az is.</p>]]></content:encoded>
			<wfw:commentRss>http://cubussapiens.hu/2009/10/fejlesztes-metodikak-ortogonalis-kodok/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Törött ablakok és hitelek</title>
		<link>http://cubussapiens.hu/2009/03/torott-ablakok-es-hitelek/</link>
		<comments>http://cubussapiens.hu/2009/03/torott-ablakok-es-hitelek/#comments</comments>
		<pubDate>Mon, 09 Mar 2009 18:36:01 +0000</pubDate>
		<dc:creator>Stampie</dc:creator>
				<category><![CDATA[Fejlesztés]]></category>
		<category><![CDATA[programozás]]></category>
		<category><![CDATA[tervezés]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Az utóbbi időben volt szerencsém elolvasni néhány érdekes írást programozástechnikáról. Ez nem arról szól, hogy a Java/C#/C++/Lisp nyelven jó programokat írni (noha az is hasznos olvasnivaló lehet), hanem inkább afféle ötleteket mutat, amik a programozási munka menedzsmentjéhez tartoznak.

Igen, erről nem véletlen, hogy egyeseknek a [[A programozás technológiája&#124;PT]] jut eszébe, de szerintem annál jóval gyakorlatiasabb dologról van szó. :) Persze ezt az én erőteljesen elfogult véleményem mondatja csak velem, nyilván másnak ugyanolyan használhatatlan dologról van szó.
]]></description>
			<content:encoded><![CDATA[<p>Az utóbbi időben volt szerencsém elolvasni néhány érdekes írást programozástechnikáról. Ez nem arról szól, hogy a Java/C#/C++/Lisp nyelven jó programokat írni (noha az is hasznos olvasnivaló lehet), hanem inkább afféle ötleteket mutat, amik a programozási munka menedzsmentjéhez tartoznak.</p>
<p>Igen, erről nem véletlen, hogy egyeseknek a PT jut eszébe, de szerintem annál jóval gyakorlatiasabb dologról van szó. <img src='http://cubussapiens.hu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Persze ezt az én erőteljesen elfogult véleményem mondatja csak velem, nyilván másnak ugyanolyan használhatatlan dologról van szó.</p>
<p>Nem tudom, mennyire ismert a „törött ablakok elmélete” (<a href="http://www.sjvgreens.org/broken.shtml">Broken Window Theory</a>), ezért megpróbálom röviden összefoglalni. A fő gondolata, hogy ha egy civilizált környéken betörik egy ablak (lehet autóé, házé), és senki nem foglalkozik vele &#8211; itt most nem arra gondolok, hogy aki betörte, annak bűntudata lesz tőle, de azt beleértem, hogy a javítás idejére bedeszkázzák, &#8211; akkor ez közepesen hosszú távon (akár néhány hónap alatt) az egész környéken a környék leromlásához, illetve a(z akár súlyosabb) bűnesetek számának növekedéséhez vezethet.</p>
<p>Ez a hatás nagyjából úgy keletkezhet, hogy az emberek azt látják, hogy más nem foglalkozik a problémákkal, ezért nem érzi úgy, hogy neki is tennie kell valamit. Ha valaki kételkedik az állítás igazságában, gondoljon bele, hogy hol szedne fel nagyobb eséllyel véletlenül elejtett papírzsebkendőt: a Nyugatinál a metróaluljáróban vagy egy öt csillagos hotelben a francia Riviérán.</p>
<p>Hogy ez hol jön a programozáshoz? <a href="http://www.artima.com/intv/fixitP.html">Az elv ott is alkalmazható</a>: ha nem foglalkozol a kis hibákkal, akkor aki később kapcsolódik, azt fogja látni, hogy az elődje sem gondoskodott róla, hogy elkerülje ezeket, ő sem fog vele foglalkozni (annyira). Aki dolgozott már ilyen kóddal, az tudja, miről beszélek. <img src='http://cubussapiens.hu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Mik ezek a kis hibák? Warningok, hiányzó dokumentáció, nem kifinomult hibakezelés, gányolás&#8230; Lehetne még sorolni. És ezeket többnyire csak akkor lehet megfelelően kezelni, ha mindenki az első pillanattól fogva odafigyel ezekre, különben annyira elszaporodnak, hogy a kezelésük szinte reménytelen (próbált már valaki 1000-es nagyságrendben warningokat javítgatni?).</p>
<p>Jó, mi a teendő olyankor, amikor közeleg a határidőt, és még rengeteg mindent implementálni kell? Nos, ekkor jön a <a href="http://softwareindustrialization.com/BruteForceDevelopmentBFD.aspx">Brute Force Development</a>: kódolunk, gányolunk, és reménykedünk, hogy működni fog. Gondolhatnánk, hogy ez rossz, de a gyakorlatban elkerülhetetlen. Ez nagyon gyakran „törött ablakokhoz” vezethet (nem, most kivételesen nem arról beszélek, hogy a legálisan beszerzett Windows-unk crackeltté válik <img src='http://cubussapiens.hu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ).</p>
<p>Természetesen ez rossz, de mivel elkerülhetetlen, ezért kénytelenek vagyunk kezelni. Erre a kezelésre ad egy módszert a technológiai tartozás (<a href="http://www.codinghorror.com/blog/archives/001230.html">Technical Debth</a>) fogalma.</p>
<p>Ez a valós életbeli adósságok fogalmához kapcsolódik: felveszünk hitelt, hogy valami lehetőséget időben kihasználjunk (nem kell 20 évet várnunk egy lakásra, és közben albérletben élni, hanem most beköltözünk), de ez nincs ingyen (20 évig fizetjük a részletet). Akkor ne vegyünk fel hiteleket? De, ha van valami helyzet, amit így értelmesen kihasználhatunk, hosszabb távon pénzt spórolhatunk meg, akkor fel lehet venni, de ésszel. Nagyon oda kell figyelni a hitelek visszafizetésére (lásd még: válság <img src='http://cubussapiens.hu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ).</p>
<p>A programozásban ehhez hasonlóan, ideiglenesen nem a legjobb, legügyesebb, legszebb megoldást választjuk, hanem rosszabb megoldást választunk, tákolunk, gányolunk. És mondjuk magunknak dokumentáljuk, hogy mik ezek a részek, és ezzel foglalkozni kell. Mi lehet ennek az értelme? Határidő, esetleg azt mondani, hogy ha működik, akkor kiadjuk, és utána belül foltozzuk a következő verzió fejlesztésének első lépéseként.</p>
<p>De természetesen itt is figyelni kell, ugyanis ha túl sok efféle dolgot hagyunk benne a rendszerben, akkor később ennek az lehet a következménye, hogy ahhoz, hogy új funkciót adjunk hozzá, nagyságrendekkel több munkát kell befektetni, mint az ideális lenne.</p>
<p>Saját tapasztalataim alapján is igazolni tudom ezt az elvet: az elmúlt héten a saját kódomat próbáltam nagyságrendekkel javítani, hogy új funkciókat adjak hozzá. Ok, vettem a fáradtságot, hogy +20% munkával javítsam azt, amit a TDK előtt BFD-vel befejeztem (visszafizettem a technológiai tartozás egy részét), annak érdekében, hogy a rendszer jobban használható legyen.</p>
<p>Remélem, hasznos/érdekes, amit most felvetettem, ha másnak van véleménye, kiegészítése, nagyon szívesen veszem bármilyen formában, más tapasztalataiból tanulni igenis jó dolog. <img src='http://cubussapiens.hu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>]]></content:encoded>
			<wfw:commentRss>http://cubussapiens.hu/2009/03/torott-ablakok-es-hitelek/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>TDK &#8211; egy nagy projekt utóélete</title>
		<link>http://cubussapiens.hu/2008/11/tdk-egy-nagy-projekt-utoelete/</link>
		<comments>http://cubussapiens.hu/2008/11/tdk-egy-nagy-projekt-utoelete/#comments</comments>
		<pubDate>Thu, 20 Nov 2008 05:34:11 +0000</pubDate>
		<dc:creator>Stampie</dc:creator>
				<category><![CDATA[Egyéb]]></category>
		<category><![CDATA[dokumentum]]></category>
		<category><![CDATA[modelltranszformáció]]></category>
		<category><![CDATA[statikus analízis]]></category>
		<category><![CDATA[tdk08]]></category>
		<category><![CDATA[tervezés]]></category>
		<category><![CDATA[visszatekintés]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Az elmúlt időszak egyik fontos eseménye volt az, hogy részt vettem a kari TDK konferencián. Ez azzal járt, hogy az elmúlt néhány hónapban minden ismerősömet azzal kergettem az őrületbe, hogy legtöbbet erről beszéltem velük...

Most viszont az egész véget ért, ideje számot vetni, értékelni, ami elkészült, és a tanulságokat levonni.<!-- break --!>

]]></description>
			<content:encoded><![CDATA[<p>Az elmúlt időszak egyik fontos eseménye volt az, hogy részt vettem a kari TDK konferencián. Ez azzal járt, hogy az elmúlt néhány hónapban minden ismerősömet azzal kergettem az őrületbe, hogy legtöbbet erről beszéltem velük&#8230;</p>
<p>Most viszont az egész véget ért, ideje számot vetni, értékelni, ami elkészült, és a tanulságokat levonni.</p>
<p>Számomra ez nagy projekt volt: 4 hónap kódolás, 1 hónap dolgozatírás, és mellé még ez-az kapcsolódott (pl. prezentáció készítése). A méretre jellemző még, hogy 5000 sor Java kódot írtam (ez nagyobb, mint bármilyen projekt, aminek a fejlesztésébe belefolytam, és a többi projektet ráadásul nem is egyedül kódoltam), valamint <a href="http://cubussapiens.hu/2008/11/modelltranszformaciok-statikus-analizise-tdk-dolgozat/">61 oldal dokumentációt</a> (szintén rekorder méret), ráadásul angolul.</p>
<p>Sokféle új dolgot próbáltam ki menet közben (vagy használtam nagyobb méretben, mint korábban): Eclipse alapú fejlesztés, kényszerkielégítés (CSP/CLP) vagy éppen nagy dokumentumok szerkesztése LaTeXben. És persze Java rulez:D</p>
<p>Ami kicsit fájdalmasabb rész, az a tanulságok levonása: sajnos sikerült a szükségesnél kicsit nagyobbat markolni, aminek az lett a vége, hogy a befejezés kicsit rohanós lett. Ráadásul bejött a szokásos problémák egyike, mármint sikerült belefutni egyes implementációs/elvi szintű problémákba, amik megkerülésére vannak ötletek, de azért még időt igényel.</p>
<p>Ráadásul a negyedik-ötödik hónapra a kezdeti lelkesedés is elfogyott, így a morál csökkent. Valószínűleg könnyebb lenne fenntartani a lelkesedést, ha lenne még egy ekkora állat, aki hajlandó a projekttel foglalkozni &#8211; különösebb ellentételezés nélkül &#8211; azzal sajnos nem tudok szolgálni, munka viszont van bőven&#8230; Persze álmodozni lehet.</p>
<p>Ami még hasonlóan fontos kérdés, hogy hasznos volt-e a befektetett energia. Na, ez az, ami jó kérdés: rövid távon kifejezetten nehéz aprópénzre váltani, amit összeszedtem (pláne, hogy a cucc még nem is 100%-os), de hosszabb távon remélhetőleg hasznosabb lesz: felhasználható diplomamunkába, esetleg cikkekhez, doktoranduszi kutatási téma alapja lehet, stb.</p>
<p>De legalább az a veszély nem fenyeget, hogy a projekt hirtelen véget ér. A hiányokat lehet pótolni, illetve néhány újdonságot is lehet csinálni. De addig is irány a régi grind&#8230;</p>
<p>Ja, és megpróbálok majd gyakrabban írni az oldalra. <img src='http://cubussapiens.hu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Tudom, ilyet már mondtam, de próbálkozni lehet. Mások újévkor fogadnak meg mindig olyan dolgot, amit nem tartanak meg, én ezért nem ígérek semmit senkinek &#8211; elég lesz magammal elszámolnom.</p>
<p><strong>Update</strong>: amit elfelejtettem, az az, hogy szeretnék köszönetet mondani mindenkinek, aki bármilyen aprósággal hozzájárult a munkához, gondolok itt azokra is, akik nem szerepelnek a dokumentáció köszönetnyilvánításában. Tényleg mindenkinek nagyon hálás vagyok.</p>]]></content:encoded>
			<wfw:commentRss>http://cubussapiens.hu/2008/11/tdk-egy-nagy-projekt-utoelete/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>2D adatszerkezet modellezése Javában</title>
		<link>http://cubussapiens.hu/2008/09/2d-adatszerkezet-modellezese-javaban/</link>
		<comments>http://cubussapiens.hu/2008/09/2d-adatszerkezet-modellezese-javaban/#comments</comments>
		<pubDate>Thu, 18 Sep 2008 21:00:49 +0000</pubDate>
		<dc:creator>thSoft</dc:creator>
				<category><![CDATA[Fejlesztés]]></category>
		<category><![CDATA[adatszerkezet]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[tervezés]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[&#8230;avagy hogyan lehet pozitív tulajdonság a gyengeség és a lustaság. Arról a gyakran előforduló modellről van szó, amikor sorok és oszlopok metszeteiben rácselemek csücsülnek, melyek automatikusan létrejönnek a nekik megfelelő sor-oszlop párra való hivatkozáskor, valamint automatikusan megszűnnek soruk vagy oszlopuk törlése esetén. A megvalósítás kézenfekvőnek tűnik: a sorokban/oszlopokban egy map-ben tároljuk az oszlopokkal/sorokkal indexelve a [...]]]></description>
			<content:encoded><![CDATA[<p>&#8230;avagy hogyan lehet pozitív tulajdonság a gyengeség és a lustaság. <img src='http://cubussapiens.hu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Arról a gyakran előforduló modellről van szó, amikor sorok és oszlopok metszeteiben rácselemek csücsülnek, melyek automatikusan létrejönnek a nekik megfelelő sor-oszlop párra való hivatkozáskor, valamint automatikusan megszűnnek soruk vagy oszlopuk törlése esetén.<br />
A megvalósítás kézenfekvőnek tűnik: a sorokban/oszlopokban egy map-ben tároljuk az oszlopokkal/sorokkal indexelve a rácselemeket.<br />
<!--break--><br />
Valahogy így:</p>
<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Node <span style="color: #009900;">&#123;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Column <span style="color: #009900;">&#123;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Row <span style="color: #009900;">&#123;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Map</span> nodes <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">HashMap</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">Map</span> getNodes<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #000000; font-weight: bold;">return</span> nodes<span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>Mi a gond ezzel?</p>
<ul>
<li>Ha törlünk egy oszlopot, az összes sor map-jében még ott marad a rá mutató referencia, mint kulcs. Ez memory leakhez vezet: a szemétgyűjtő nem tudja eltakarítani a &#8220;zombi&#8221; oszlopokat és a hozzájuk tartozó, ugyancsak zombi rácselemeket. Ez ráadásul az adatstruktúra perzisztálásánál is problémát jelent.</li>
<li>Hogyan s mikor hozzuk létre a rácselemeket? Mindig, amikor létrehozunk egy oszlopot? Ezt jobban lehetne automatizálni, ráadásul ha nem minden rácspontba akarunk elemet tenni, fölöslegesen hozzuk létre ezeket.</li>
</ul>
<p>Több megoldás is lehetséges, gondolhatnánk elsőre:</p>
<ul>
<li>Gondolkodhatnánk egy címkézett gráfban, és a beépített kollekciók helyett alkalmazhatnánk valamiféle gráfkezelő könyvtárat, pl. a <a href="http://jgrapht.sourceforge.net">JGraphT</a>-t, mely gondoskodik csúcs törlésekor a hozzá tartozó élekről.</li>
<li>Kibővíthetnénk a lista adatszerkezetet eseménykezelőkkel, melyek elem hozzáadásakor és törlésekor végrehajtanak egy megadott kódot.</li>
</ul>
<p>Azonban a probléma megoldható a Java Collections Framework keretein belül, karöltve természetes kiegészítőjével, a <a href="http://larvalabs.com/collections">Collections Generic</a> API-val (a <a href="http://jakarta.apache.org/commons/collections">Commons Collections</a> generikus változata). Nehogy már egy ilyen általános jelenséget ne tudjunk a megannyi hasznos absztrakciót tartalmazó Java nyelv elemeivel modellezni! A kulcsfogalom a <em><a href="http://java.sun.com/javase/6/docs/api/java/lang/ref/WeakReference.html">gyenge referencia</a></em>, mellyel befolyásolhatjuk a garbage collector működését, ezzel rábízva az elárvult elemek törlését.</p>
<p>Javában az alapértelmezett referencia erős (strong), de ezenkívül még létezik a gyenge (weak), lágy (soft) és fantom (phantom) referencia. A weak reference lényege, hogy amennyiben egy objektumra csak ilyenek mutatnak, a szemétgyűjtő teljes lelki nyugalommal eltakarítja. Nekünk pont ez a viselkedés jön kapóra: a map-ben gyenge referenciákat fogunk csak tárolni az oszlopokra/sorokra. (A másik két típus most nem érdekes számunkra, pedig azok is hasznosnak bizonyulhatnak más esetekben.)</p>
<p>A Collections API tartalmazza a <a href="http://java.sun.com/javase/6/docs/api/java/util/WeakHashMap.html">WeakHashMap</a> osztályt, mely a <a href="http://java.sun.com/javase/6/docs/api/java/util/HashMap.html">HashMap</a>-hez hasonló, azonban kulcsai gyenge referenciák. A WeakHashMap ezeket átlátszóan kezeli, önmagától létrehozva és dereferálva nekünk őket. Így programunkban az automatikus törléshez csak két dolgot kell módosítanunk: HashMap helyett WeakHashMap-et használunk, és a kívánt pillanatban meghívjuk a garbage collectort.</p>
<p>A létrehozás pedig <em>lusta map</em> segítségével történik: a rácselemek példányosítása akkor és csak akkor történik, amikor először hivatkozunk az őket azonosító sor-oszlop párosra. Ehhez is kész eszközt kapunk a kezükbe a Collections Generic Libraryben: a <a href="http://collections.sourceforge.net/api/org/apache/commons/collections/map/LazyMap.html">LazyMap</a>-et és az <a href="http://collections.sourceforge.net/api/org/apache/commons/collections/functors/InstantiateFactory.html">InstantiateFactory</a>-t, melyek a Decorator és a Factory pattern alkalmazásával érik el céljukat.</p>
<p>Imhol a forráskód módosított része. Figyelemreméltó, hogy mennyi minden változott&#8230;</p>
<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Row <span style="color: #009900;">&#123;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">protected</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">Map</span> nodes <span style="color: #339933;">=</span> LazyMap.<span style="color: #006633;">decorate</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">WeakHashMap</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, <span style="color: #000000; font-weight: bold;">new</span> InstantiateFactory<span style="color: #009900;">&#40;</span>Node.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// !</span><br />
<br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>És egy kis tesztosztály, a kiértékelés a kedves olvasó feladata:</p>
<div class="codecolorer-container java mac-classic" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:600px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br /></div></td><td><div class="java codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> GridTest <span style="color: #009900;">&#123;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; Grid grid <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> Grid<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> <span style="color: #cc66cc;">2</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; grid.<span style="color: #006633;">getRows</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> Row<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; grid.<span style="color: #006633;">getColumns</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">new</span> Column<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>Row row <span style="color: #339933;">:</span> grid.<span style="color: #006633;">getRows</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>Column column <span style="color: #339933;">:</span> grid.<span style="color: #006633;">getColumns</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span>row.<span style="color: #006633;">getNodes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>column<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; grid.<span style="color: #006633;">getColumns</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">remove</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #003399;">System</span>.<span style="color: #006633;">gc</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// !</span><br />
&nbsp; <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>Row row <span style="color: #339933;">:</span> grid.<span style="color: #006633;">getRows</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>Column column <span style="color: #339933;">:</span> row.<span style="color: #006633;">getNodes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">keySet</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span>row.<span style="color: #006633;">getNodes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>column<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; <span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>Hát ilyen power a Collections Framework, amint már Stampie is <a href="http://cubussapiens.hu/2008/08/java-rendezes-avagy-hogyan-ne-tegyuk/">rámutatott</a>, ami pedig esetleg hiányzik belőle, azt a Collections Generic pótolja. Mi a tanulság? Használjuk ki a nyelvi lehetőségeket, amelyek rendelkezésünkre állnak!</p>]]></content:encoded>
			<wfw:commentRss>http://cubussapiens.hu/2008/09/2d-adatszerkezet-modellezese-javaban/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
