ugrás a tartalomhoz

Ismerkedés a TDD szépségeivel...

eddig bírtam szó nélkül · 2012. Szep. 4. (K), 22.34
Végre rászántam magam, hogy gyakorlatban is kipróbáljam a Unit Test-ekről olvasottakat, de szokás szerint bizonytalan vagyok, hogy jó úton járok-e. Ehhez kérném a segítségetek!

Ez lenne a unit teszt:

import unittest
import sqlite3
import szemetes

class TestDBFactory(unittest.TestCase):


    def test_getInstance_returnValue(self):
        # ez itt kicsit borítja a tiszta kód elveket, mert konkrétan azt ellenőrzi,
        # amihez semmi köze: valóban egy sqlight3 példányt ad-e vissza a getInstance()?
        self.assertIsInstance(szemetes.DBFactory.getInstance(),sqlite3.Connection, 
                              u"Nem sqlite3 példányt ad vissza a getInstance")
    
    def test_getInstance_returnsSameInstance(self):
        dbInstance1=szemetes.DBFactory.getInstance()
        dbInstance2=szemetes.DBFactory.getInstance()
        self.assertEqual(dbInstance1, dbInstance2, u"Azonos adatbázisnév ellenére eltérő instance-t ad vissza!")
 
    def test_getInstance_raisesException(self):
        # Hibás fájlnév esetén exceptiont kell kapnom
        # A /dev/zero unix alatt (elvileg) csak olvasható, windows alatt meg nem létezik, tehát elvileg
        # megfelel a feltételnek
        self.assertRaises(sqlite3.OperationalError, szemetes.DBFactory.getInstance,"/dev/zero")


        
if __name__ == "__main__":
    #import sys;sys.argv = ['', 'Test.testName']
    unittest.main()
ez pedig a tesztelendő kód:

import sqlite3 as db

class DBFactory(object):
    databaseObjects = {}
    
    @classmethod
    def getInstance(cls,databaseName=':memory:'):
        if databaseName not in cls.databaseObjects.keys():
            cls.databaseObjects[databaseName]=db.connect(databaseName)
        return cls.databaseObjects[databaseName]
Tekintsünk el attól, hogy Pythonban íródott, vegyük úgy, hogy pszeudo kód!
Ha valaki nem ismerné, a self helyettesíti a PHP-ben használatos $this-t, a cls pedig a statikus metódusokban a saját osztályt jelöli.

Pár alapelvet felrúgok azzal, hogy "bedrótozom" az sqlite3 használatát, de nem akartam túlbonyolítani.

A fenti osztály feladata annyi, hogy visszaadjon egy sqlite3.Connection példányt a paraméterként megadott adatbázishoz. Ha még nem létezik a megadott névhez tartozó példány, akkor létrehoz egy újat, ha már létezik, akkor a létezőt adja vissza. Amennyiben nincs megadva paraméter, akkor egy memóriában létrehozott adatbázist fog használni.

Kellőképp primitív feladat a gyakorláshoz, néhány sor az egész, ehhez képest csak azok a tesztek, amiket én ki tudtam találni... Már az is soknak tűnik.
  1. Vajon megfelelő típusú objektumot kapok-e?
  2. Ha kétszer lekérem ugyanazzal a paraméterrel, akkor nem hoz-e létre egy új kapcsolatot?
  3. Valóban hibára fut, ha hibás fájlnevet kap?
A 2.-at sikerült úgy kódolni és tesztelni, ahogy a "nagykönyvben meg van írva" :-)
(elfelejtettem ellenőrizni, hogy létezik-e már az adott névhez tartozó példány, így a második kérés új példányt hozott létre)
A 3.-kal meg... nos ott jöttem rá, hogy mennyire nem triviális ez az egész dolog. Ugyanis az assertRaises-t első menetben rosszul paramétereztem emiatt bármit írtam a paraméterek közé, mindig sikeres volt a teszt. Később jutott eszembe, hogy mi lenne, ha ellenpróbát csinálnék, amivel biztosan failed lesz az eredmény. Nem az lett... :-)

És itt a kérdés: egyáltalán az, amit eddig megírtam, kb. rendben van-e vagy valahol tévúton járok?
A másik: hogyan szokás a teszteket tesztelni, hogy valóban azt tesztelik-e amit...
Ezekre automatizált tesztet írni hülyeség (gondolom én). Marad a manuális tesztelés, de mi van, ha később a teszteken kell módosítani?
 
1

Engem már régóta idegesít,

inf · 2012. Szep. 5. (Sze), 00.37
Engem már régóta idegesít, hogy csak néhány brush van bent kódszínezésre (js, html, xml, php, sql, cmd, azt hiszem ennyi...). Ehhez képest a szerkesztési tippeknél le van írva, hogy még kismillió nyelv támogatott, csak egyikhez sincs betöltve a javascript, ami ezt lehetővé tenné. Szerintem nem együl vagyok, aki szívesen látná pl az ebben a postban lévő python kódon színezve. (Annyit tudtam tenni az ügy érdekében, hogy kiszedtem a szürke hátteret, és beraktam cmd alá, hogy egy fokkal olvashatóbb legyen.)
3

Köszi és igen, nem vagy

eddig bírtam szó nélkül · 2012. Szep. 5. (Sze), 03.27
Köszi és igen, nem vagy egyedül. Bár attól tartok, rajtam kívül nem nagyon van itt olyan, aki pythonnal játszadozna.

Én is elsősorban (ahogy írtam) inkább "pszeudo kódként" használom, de ez legalább olyan, ami le is fut, ha kell. :-)
5

Miert?

janoszen · 2012. Szep. 5. (Sze), 06.12
Miert nem? En szoktam Pythonban fejleszteni. :)
6

Miért nem(annyira) Python?

eddig bírtam szó nélkül · 2012. Szep. 5. (Sze), 08.00
Egyrészt nem nagyon látom, hogy kapkodnának a pythonos programozók után. (néha egy-egy django-s, de a django-tól elment a kedvem)
Másrészt eddig még nem láttam komoly projektet, ami a pythonos indítás után néhány évvel ne íródott volna át valami egyéb nyelvre. (most nem ugrik be, de valamelyik linuxos admin program is ilyen volt)
Harmadrészt még mindig ott tartok, hogy inkább az elméleti dolgok érdekelnek, egyre kevésbé a gyakorlati megvalósítás (ez utóbbi csak azért van így, mert már biztos vagyok benne, hogy többé nem találok munkát és annyira már nem köt le ez a játék, hogy elég komolyan és mélyen belemásszak)

Az meg már csak apróság, hogy rajtam kívül itt még nem nagyon kérdezősködött senki pythonos témában, ebből feltételezem, hogy a többséget nem igazán érdekli.
9

Ne vicceljünk

janoszen · 2012. Szep. 5. (Sze), 09.05
Szerintem tudok olyan helyet, ahol a python tudásra azt mondják, hogy haza se menj.
10

Jó, nem viccelek

eddig bírtam szó nélkül · 2012. Szep. 5. (Sze), 09.46
Bár már valamennyire beleástam magam (jó, nem full profi szinten, de annyira, amennyire anno a perl-t ismertem, annyira már a pythont is), de volna rá egy karton söröm, hogy engem még onnan is röhögve küldenének melegebb éghajlatra.

És nem haladok, mert már megint OOP elméleten rágódok, ahelyett, hogy csinálnám lesz-ami-lesz... :-(
11

Erteni

janoszen · 2012. Szep. 5. (Sze), 09.48
Nyilvan erteni kell hozza. :)
12

Nem a hozzáértésre céloztam.

eddig bírtam szó nélkül · 2012. Szep. 5. (Sze), 10.00
Nem a hozzáértésre céloztam. :-)

VMS-hez, Oracle üzemeltetéshez értettem, mégsem kellettem sehova. Még annyira sem, hogy interjúra behívjanak.
VMS volt a kellemetlenebb, mert ahhoz azért elég ritkán lehet embert találni manapság. A hirdetésben rendszergazdát kerestek. Hónapokkal később derült ki, hogy valójában csoport- vagy osztályvezetőt, aki ért a VMS üzemeltetéshez is...
17

kulfold

Greg · 2012. Szep. 5. (Sze), 14.51
kulfoldon eleg sok python allas van. de ha nincs tapasztalat, akkor nem sokat er az elmeleti tudas. mondjuk kulfoldon eleg sok a fejleszto allas. engem hetente tobbszor keresnek anglia rails melokkal, mert par fejvadasznak bekerultem az adatbazisaba regebben.
18

a Rails az Ruby, nem Python

eddig bírtam szó nélkül · 2012. Szep. 5. (Sze), 15.16
a Rails az Ruby, nem Python ;-)
Egyébként (20+ évvel ezelőtti) gyakorlati tapasztalatom van. Amíg procedurálisan is szabad gondolkodni, addig nincs nagy gáz, csak a nyelv rigolyáit kell megtanulni.
Nekem most leginkább az OOP okoz gondokat, mert nehezen olvasok és türelmetlenkedek állandóan.
19

nem mondod?

Greg · 2012. Szep. 5. (Sze), 15.49
:). csak a viszonyitas miatt irtam. a ruby kevesbe elterjedt es popularis mint a python es tapasztalatbol tudom hogy abban rengeteg melo van, ezert gondolom pythonban megtobb. oop ma mar alapkovetelmeny szerintem mindenhol.

http://www.indeed.com/jobanalytics/jobtrends?q=python&l=
http://www.indeed.com/jobanalytics/jobtrends?q=ruby&l=
http://www.indeed.com/jobanalytics/jobtrends?q=php&l=
20

Bocs, nekem nem tűnt fel. A

eddig bírtam szó nélkül · 2012. Szep. 5. (Sze), 16.04
Bocs, nekem nem tűnt fel.
A Ruby, mint önálló nyelv, valóban nem olyan elterjedt, de a RoR azt hiszem, lényegesen népszerűbb, mint mondjuk a django.
Mondjuk én a külföldi hirdetéseket eleve nem nézem (öreg vagyok már a költözéshez), a hazaiak közt meg csak elvétve látok ilyesmit. Nem szoktam célzottan keresni, csak az elém kerülő állásajánlatok alapján gondolom így.
2

Elsőnek szögezzük le, hogy

inf · 2012. Szep. 5. (Sze), 01.20
Elsőnek szögezzük le, hogy amit te próbálsz, az nem unit test, hanem integrációs teszt. Az a különbség, hogy a unit test-nél teljes egészében te írod a kódot, amit tesztelsz, az integrációs tesztnél meg egy külső lib-et emelsz be, és ahhoz írsz valamilyen csatolót, mint pl itt ezt a db provider-t.

Alapból ennek úgy kéne mennie, hogy fejben megszületik, hogy mondjuk te akarsz valamit, ami neked szórja az sqlite3 adatbázis kapcsolatokat.
Csinálsz neki egy interface-t, elnevezed SqliteConnectionContainerInterface-nek (vagy ami neked tetszik), ebbe teszel egy metódust,
  1. aminek a bemenő paramétere az adatbázis neve,
  2. a kimenő paramétere meg hogy milyen típust ad vissza.
  3. Mivel kapcsolatokat adsz vissza, ezért a kivételeket - amiket az sqlite3 vissza tud adni - szintén fel kell tüntetni ennél a metódusnál, vagy csinálsz egy, esetleg több saját kivételt, amivel majd elfeded ezeket (ez a te döntésed).
  4. Ha mindez megvan, akkor még eszedbe jut, hogy a te konkrét megvalósításodban, az SqliteConnectionProvider-ben olyat akarsz, hogy egy adatbázishoz egy kapcsolat tartozzon.

Szerintem elég logikus, hogy mihez kell itt tesztet írni:
Nyilván minden egyes kivétel típusra, vagy olyan esetre, ami az adott típust kiváltja külön tesztet kell írni (nem string adatbázis név, nem tud kapcsolódni, nincs joga kapcsolódni, stb...). Ezen kívül minden elvárt funkcióra tesztet kell írni (visszaadott érték, adott néven lévő kapcsolat tartása, stb...).

Ami hiányzik nálad annak ellenőrzése, hogy string-e az adatbázis név (mondjuk ezt megteszi helyetted az sqlite connection is, mert gondolom elszáll, ha ilyet adsz neki). A kapcsolat tartását én egy kicsi ciklusban (legalább 3 érték) ellenőrizném 2 érték helyett, de ez is csak apróság. Ha IDE-t használnál, akkor nem tudnád elrontani a sorrendet az assertRaises-nél, az automatikus kiegészítés miatt...
Ha elég logikusan gondolkodsz, és pl az SRP-t szem előtt tartod, akkor nem nagyon fognak változni a tesztjeid, egyébként ha mégis így lenne, akkor őket is refaktorálni kell. Egyébként is kell, mert ki kell emelni belőlük az ismétlődő részeket... A tesztek helyességét nem szokták tesztelni, azt neked kell megmondani ránézésre.
4

Integrációs?

eddig bírtam szó nélkül · 2012. Szep. 5. (Sze), 03.50
Köszi szépen, hogy foglalkoztál vele!
Lenne pár megjegyzésem - nem értek mindenben egyet azzal, amit leírtál.

Összességében itt a DBFactory elnevezésű osztály egyetlen, "statikus" metódusának működését tesztelném. Ebből az exception tesztelése valóban kilóghat, azt lehet, hogy külön kellene tesztelni annak fényében, amit írsz.ű
A 2. pont nem stimmel (vagy én nem értem, mire gondolsz), mert a metódus kimenete nem egy típus, hanem maga az objektum.

Adatbázis nevének a szintaktikáját nem igazán tudom ellenőrizni egy multiplatform rendszer esetében. Linuxon, megfelelő fájlrendszert használva szinte bármilyen karaktert (ha jól emlékszem, még unicode karaktereket is) tartalmazhat a név, talán a \000-t leszámítva, de Windows-on is meg kell erőltetni magam, ha érvénytelen fájlnevet próbálok kreálni. (leginkább nem létező könyvtárra v. olyanra hivatkozva, amihez nincs jogom hozzáférni)

Ami a hibásan használt asserRaises-t illeti...
Eclipse-t használok PyDev kiegészítéssel és egy apró félreértés miatt nem tudtott közbeszólni a kódkiegészítő sem, hogy hülyeséget csinálok.
Most nincs előttem doksi, de pl. az assertEqual-nak három paramétere van: a két hasonlítandó érték és egy üzenet, ami megjelenik a logban, ha hibás a teszt:
self.assertEqual(a,b,"üzenet")
Az assertRaises meg így kellene, hogy kinézzen:
self.assertRaises(Exception, tesztelendo.objektum, param1, param2, ... paramn)
ami helyett én ilyet írtam:
self.assertRaises(Exception,tesztelendo.objektum(param1),"üzenet")
Szintaktikailag rendben lenne, csak egészen mást csinál, mint amit szeretnék. :-)

Hogy a későbbiekben mennyire változnak a tesztek... Azt hiszem, épp a Tiszta kódban olvastam, hogy azért azok is változhatnak, nem véletlenül kell ezeket a kódokat is "tisztán" tartani. Itt pl. kapásból feltételezem, hogy most csak azért keletkezett a féloldalnyi teszt, mert ismerkedni próbálok a környezettel. De pl. ha ezt az adatbázis kapcsolatokat előállító osztályt nézem, amint kicsit általánosabbra próbálom alakítani, hogy ne csak sqlite kapcsolatokkal tudjon foglalkozni, máris borulhat az eddig megírt teszt (bejöhet újabb paraméter, lehet, hogy a statikus osztály kevés lesz, példányosítani kell a konstruktornak átadva a szükséges drivert stb.)
Legalábbis én így képzelném.
13

Persze, változhat a teszt, ha

inf · 2012. Szep. 5. (Sze), 12.30
Nyilván objektumot ad vissza a metódus, de annak van egy típusa, amit szintén tesztelni kell. A paraméternek szintén van típusa, amit ellenőrizni kell. Már ha nem típusos nyelvről van szó...

Persze, változhat a teszt, ha az elvárásai változni a factory-vel kapcsolatban, vagy változik a külső lib, amihez csatolót írsz. Ezért szokták az integrációs teszteket minden ilyen külső lib váltáskor lefuttatni, hogy lássák, hogy lesz e a gond a váltással, illetve ezért szoktak saját adaptereket az ilyen külső libek fölé tenni, hogy csökkentsék a függőséget. Ha pl változik a külső lib, akkor elég az adaptert átírni, ami sokkal kisebb munka, mint minden egyes metódust átírni, ami adatbázist használ...

Ja hát clean code esetében is megírták, hogy max 2 paraméter, aminél még könnyen fejben lehet tartani, hogy melyik melyik, 3 paraméter meg már sok... Én pl assertRaises-nél már map-et adnék át, vagy egy külön objektumot. Js-ben mondjuk ez nem okoznak nagy gondot (object literal), php-ben sem (asszociatív tömb), gondolom python-ban is megoldható valahogy...

Ha magasabb absztrakciós szintekről haladsz lefele, és jól csinálod, akkor úgy változhat meg a teszt, ha kód ismétlődést találsz, és azt emeled ki. Nyilván erre is megvannak az átmeneti megoldások, hogy az ilyest hogyan kell csinálni. A másik, amikor megváltozik a teszt, ha változik az adott osztály funkciója. Mondjuk az ügyfél rájön, hogy egy nagyon picit mást akart, pl egy találati listánál plusz egy filter-t be kell tenni, vagy bármi ilyesmi... Ezek a dolgok az esetek nagy részében nem járnak nagy változással szerintem. Egyébként én is csak próbálgatom a TDD-t, egyelőre csak lassít a munkában...
7

Úgy hallottam úgy lehet

szjanihu · 2012. Szep. 5. (Sze), 08.39
Úgy hallottam úgy lehet ellenőrizni a teszteket, hogy random kiveszel X sort a tesztelendő kódból és ha ennek ellenére is lefutnak a tesztek, akkor nincs minden tesztelve. Vegyük észre, hogy ez nem (csak) code coverage ellenőrzésre jó.
Sajnos ennek még nem néztem utána, így toolokat se tudok mondani és egy gyors google keresés se adott releváns találatot.
8

Én valahogy úgy próbálkoztam

eddig bírtam szó nélkül · 2012. Szep. 5. (Sze), 08.46
Én valahogy úgy próbálkoztam (lehet, hogy rossz az irány, de eddig nem látom, hogy az lenne), hogy minden assert-et lefuttatok olyan feltételekkel, amiről biztosan tudom, hogy hibát kell produkálnia. Így jött ki az is, hogy az assertRaises nem működik az eredeti felállásban. :-)

Csak az érzékeny lelkemet bántja, hogy tesztelésre írok programot, amit újabb tesztekkel kellene tesztelni, de a tesztet tesztelő teszteket is tesztelni kellene... és ugye az emberi agyban a max. rekurzió mélysége valamivel kisebb, mint PHP-ben v. Pythonban. :-))
14

A teszteknek az a lényege,

inf · 2012. Szep. 5. (Sze), 12.32
A teszteknek az a lényege, hogy ránézésre nyilvánvalóak legyenek. Sajnos a teszt rendszer, amit használsz nem elég nyilvánvaló... Csinálhatod azt, hogy fölé teszel egy saját réteget, ami ezt a hibát javítja, vagy csinálhatod azt, hogy megtanulod a nem nyilvánvaló részeit, mint pl az assertRaises paraméterezése...
16

No igen, nem árt, ha az ember

eddig bírtam szó nélkül · 2012. Szep. 5. (Sze), 13.26
No igen, nem árt, ha az ember néha el is olvassa a doksit, nem csak átfutja. (ez most az az eset volt, mert az eclipse által feldobott ablak nem volt egyértelmű e téren)
21

Persze, nem árt, mondjuk ha

inf · 2012. Szep. 5. (Sze), 18.03
Persze, nem árt, mondjuk ha tudod, hogy egy teszt rendszerről van szó, és képben vagy, hogy egy teszt rendszer miket szokott csinálni, akkor szerintem inkább tervezési hiba, hogy nem egyértelmű valami benne, mintsem a te hibád...
23

Az éles kód teszteli a tesztet.

pp · 2012. Szep. 6. (Cs), 08.20
Nem kell ide rekurzió. Ugyanis ha a rossz a teszt akkor is kijön a hiba, mert az éles kód teszteli a tesztet. (lásd példádat)

pp
24

A példám épphogy nem jó, mert

eddig bírtam szó nélkül · 2012. Szep. 6. (Cs), 08.32
A példám épphogy nem jó, mert a teszt épp az elvártaknak megfelelően viselkedett, csak a helyes viselkedés oka tért el attól, amit szerettem volna. És ha nem vagyok ilyen, már-már paranoiás szinten gyanakvó a saját hülyeségemmel szemben, akkor észre sem veszem, hogy valami nem kerek. :-)
15

Elvileg minden if-hez kell

inf · 2012. Szep. 5. (Sze), 12.36
Elvileg minden if-hez kell tesztet írni, szóval ha kiveszel egy if blokkot, és a tesztek úgy is lefutnak, akkor gyengék a tesztjeid... Ez mondjuk csak első meglátás, de kézzel biztos, hogy nem szórakoznék ilyennel... Én inkább úgy vagyok vele, hogy mielőtt megírom az osztályt elgondolkodok rajta, hogy mik az elvárásaim vele kapcsolatban, és ezekre az elvárásokra írok teszteket. (Már ha írok... Tesztet akkor érdemes szerintem írni, ha nagyon határozott elképzelésed van arról, hogy mit akarsz milyen felülettel. Nálam ez még túl képlékeny, és nem tudom elég rugalmasan változtatni a tesztjeimet, hogy megérje. Túl sok időt vesz el a módosítgatásuk.)
38

Én is most olvasgatok a code

inf · 2012. Szep. 9. (V), 03.52
Én is most olvasgatok a code coverage-ről. Az arról szól, hogy lefuttatják a unit testeket a kódra, és közben nézik, hogy a kód melyik részei futnak le. pl ha van egy if statement, akkor feltételtől függően fut le a blokkja. Ha hibásak a tesztek (értsd: nem szerepel bennük minden eshetőség), akkor nem lesz 100%-os a lefedettsége a kódnak, tehát kimarad mondjuk egy if statementen belüli blokk hívása, stb... Nyilván ha ezt a blokkot eltávolítjuk, akkor attól még ugyanúgy zöldet fognak adni a tesztek, mert a blokkon belüli kódot egyik teszt sem futtatja le. Úgyhogy ez a módszer tényleg jó kód lefedettség tesztelésére, viszont biztos vagyok benne, hogy erre vannak már nagyon jó eszközök. Ha jól tudom phpunit-hoz netbeans-be van beépítve hasonló. Még nem sikerült használnom (mert windows alatt nem bírtam telepíteni a phpunit-ot), de hasznos dolognak tartom.
22

Tévedések... (offtopik)

eddig bírtam szó nélkül · 2012. Szep. 6. (Cs), 07.55
Fény derült egy újabb félreértésre (csak az assertRaises működésével kapcsolatos problémához kapcsolódva)

SRP - nem tudom, belefutott-e valaki a hibámba az értelmezésével. Ugye ez magyarra fordítva arról szól, hogy "Egy osztálynak egy és csakis egy oka lehet a változásra...".

Magamban elkönyveltem, hogy ennek így kevés értelme van, de aki kitalálta, tudja miről beszél, hát legyen...
Végre "leesett": nem az osztály működésére vonatkozik az a "változás", hanem az elkészült kódhoz a későbbiekben csak "egy" okból szabad hozzányúlni. Ha lehet több ok is az osztály kódjának megváltoztatására, akkor az az osztály nem felel meg az SRP definíciójának.
Továbbra sem teljesen tiszta, mert egy-két példát leszámítva, nehezen tudok elképzelni olyan megvalósítást, aminek a módosítását a későbbiekben ne lehetne több dologgal is indokolni - de itt már jöhet az, hogy nem igazán tudok mit kezdeni az "azonos absztrakciós szint" fogalmával...
25

SRP

T.G · 2012. Szep. 6. (Cs), 10.12
Szerintem itt valami félreértés van, nincs szó változásról. Responsibility az felelősség, tehát egy osztálynak csak egy feladata legyen.
Ez a sok kis osztály jobb, mint egy nagy osztály elve. :)
26

Mea culpa…

T.G · 2012. Szep. 6. (Cs), 10.25
Előző hozzászólás visszavonva. Tényleg arról az oldalról közelítik meg, hogyha kétféle okból kellene megváltoztatni egy osztályt, akkor azt igazából két osztállyal kellene megvalósítani...
27

Örömmel látom, hogy nem én

eddig bírtam szó nélkül · 2012. Szep. 6. (Cs), 11.25
Örömmel látom, hogy nem én vagyok az egyetlen, akit megkavar az elnevezés és a hozzáfűzött magyarázat közt látszólag nem létező kapcsolat. :-))))

Bennem mindig úgy élt ez az egész, hogy egy felelősségi kör, akkor azon az absztrakciós szintnek nevezett valamin belül egyetlen dologgal kell foglalkoznia. (pl. egy adattároló osztálynak semmi köze a benne tárolt adatok html formátumú megjelenítéséhez)
Így, hogy végre, kezdem felfogni, mit jelent az "egyetlen ok a változásra", kicsit más a leányzó fekvése.
Csak az zavar, hogy nekem még úgy tanították: ismétlődő feladatokat kell szubrutinba, függvénybe tenni. Itt meg már fellép egy olyan igény is, hogy akkor is leválasztok feladatokat az alap programról, ha csak logikailag különülnek el, de nem ismétlődnek.
(mittudomén, egy osztály konstruktorában esetlegesen elvégzendő bonyolultabb műveletek, amit korábbi tanulmányaim alapján simán beraknék a konstruktorba)
28

Szerintem ezek nem mondanak

inf · 2012. Szep. 6. (Cs), 13.13
Szerintem ezek nem mondanak ellent az előző tanulmányaidnak. Mármint először leválasztod szubrutinba. Amikor meg már látod, hogy elég nagy az osztályod, és logikailag különböző részekből áll, akkor kiemeled ezeket a részeket külön osztályokba...
29

Annyiban mondanak neki

eddig bírtam szó nélkül · 2012. Szep. 6. (Cs), 13.45
Annyiban mondanak neki ellent, hogy akkoriban még lényeges lehetett az a manapság minimálisnak számító overhead, amit a függvények meghívása, a függvény be- és kilépő részei okoztak.
Pl. már nem tudom, PL/I v. COBOL fordítónak a köztes, assembly kódját nézegettem: iszonyat mennyiségű művelet volt egy-egy ilyen fv./szubrutin hívása körül. Többféle stack létrehozása, esetenként rendszerkönyvtárakból egy-két hívás stb. majd a saját kódom, ezt követően a stackek felszabadítása, visszatérés után is némi memória rendezgetés.
Mondjuk az is igaz, hogy azoknak a gépeknek a számítási teljesítménye valahol egy 286-os PC környékén lehetett. :-)
30

Szerintem a python is úgy van

MadBence · 2012. Szep. 6. (Cs), 14.04
Szerintem a python is úgy van vele, hogy a futásidejének nagyobbik részét IO-ra várakozva tölti, tehát nem érdemes foglalkozni ilyen mikrooptimalizálással. (lásd: The First Rule of Program Optimization: Don't do it.).
Nyilván ha nincs IO, vagy számításigényes algoritmusokat futtat az ember, akkor érdemes az ilyen dolgokat végiggondolni (de mondjuk pl hd videót konvertálni amúgy sem pythonban illik).
31

Ja, előre optimalizálni

inf · 2012. Szep. 6. (Cs), 14.31
Ja, előre optimalizálni szerintem sem szükséges. Én pl most dom fával csinálom a html-t az egyik oldalnál, és előre aggódtam, hogy mennyivel lassabb lesz, mint egy sima sablonos megoldás. Hát nem volt értelme emiatt aggódni, mert teljesen jó sebességre az oldal. Meg se néztem xdebug-gal, hogy hol a szűk keresztmetszet, mert nem izgat. (Egyébként valszeg sql hívásoknál, és nem a kirajzolásnál van...)
32

OK, én ezt értem, hogy

eddig bírtam szó nélkül · 2012. Szep. 6. (Cs), 18.12
OK, én ezt értem, hogy változott a világ... Amiről én beszélek, az úgy harminc éves történet. Akkoriban még nem nagyon oktattak ilyesmit, sőt...
Nekünk még úgy magyarázták, hogy ésszel írjuk a programot, mert ugye:
- megírod valami papírra
- átírod kódlapra (ez egy programnyelvhez igazított beosztású, 80 oszlopos, A4-es papír volt)
- leadod az adatrögzítőknek, akik lyukkártyára lyukasztják.
- elkészül, amikor elkészül, visszakapod.
- leadod futtatásra
- ha épp nem sürgős, akkor lehet, hogy csak három nap múlva jön vissza vagy az eredménytáblázattal, vagy egy féldoboznyi memória dumppal.

Folytassam? ;-)
És akkor még ugye ott volt, hogy a processzor sem volt valami hűde...

Egyébként azon már többször összevitatkoztam az itteni törzsközönséggel, hogy (szerintem) az előre optimalizálás, meg a "nem csinálok olyat, amiről tudom, hogy zabálja az erőforrásokat és tudok hozzá jobb megoldást" azért nem egy kategória.
33

Általánosságban azért végtelen ideig lehet vitatkozni.

pp · 2012. Szep. 6. (Cs), 20.55
Egy függvényhívás(kettővel ezelőtti kommented) messze nem zabál annyi erőforrást mint a külső források elérése, ezért ezzel az indokkal, nehezen érthető kódot készíteni, nem lehet ma már.

Nyilván az algoritmus bonyolultságára érdemes figyelni, hisz nem mindegy, hogy 2ˆn, nˆ2, vagy C*n lépésből oldja meg a feladatot az ember(n az elemszám, C pedig egy konstans), de hogy ezen belül még optimalizáljunk a kód érthetőségének kárára, szerintem ma már nem elfogadható hozzáállás.

Az egyedül, az elefánttoronyban alkotó "zsenik" kora lejárt. Ma már sokkal fontosabb, hogy csapatban hogyan tudsz dolgozni.

Véleményem szerint aki egyedül dolgozik az is csapatban tolja, mert a fél évvel ezelőtti önmagad már egy tök más ember (ha nem akkor gáz van, mert megálltál a fejlődésben), akivel együtt kell dolgozni, mert nincs olyan, hogy na ez a program kész és használjuk száz évig.

Régen ezt így gondolták, de hibásan. Ez van. Lépjünk ezen túl.

Ha hívnak, hogy baj van, mert lassú a rendszer a leges-legutolsó-utáni dolog (sose fordult elő), hogy azért kéne egy kódhoz hozzányúlni, mert egy plusz függvényhívás van benne.

pp
34

Nem "egy" feleslegesről

eddig bírtam szó nélkül · 2012. Szep. 6. (Cs), 21.12
Nem "egy" feleslegesről beszélek, hanem rengetegről egy nagy rendszer esetében.
És bizony láttam olyat, hogy java-ban megírt rendszer alá egyre erősebb és erősebb CPU-kat kellett tolni, miközben a diszk alrendszerek változatlanok maradtak...
Pedig csak a userek száma ugrott meg egy picit. :-)
(értsd: a gyakorlati tapasztalataim totál mást mondanak, mint amiket fórumokon olvasok... Pedig nem asztali PC-ken futottak azok a rendszerek, nagyon nem...)
De mindegy, ezt a témát tényleg hagyjuk.
35

És bizony láttam olyat, hogy

inf · 2012. Szep. 6. (Cs), 21.24
És bizony láttam olyat, hogy java-ban megírt rendszer alá egyre erősebb és erősebb CPU-kat kellett tolni, miközben a diszk alrendszerek változatlanok maradtak...


Hát pont, hogy ilyenkor kellett volna belenézni a kódba, és optimalizálni. Gondolom senki nem tette meg, mert egyszerűbb volt vasat tolni alája. Nem értem, hogy ez az egész hogy jön ide... Semmi köze a plusz néhány függvény híváshoz. Senki nem mondja meg hasraütésre, hogy mitől lassú a kód, azért kell profiler. Te maximum gyaníthatod, hogy mi miatt lehet, aztán vagy úgy van, vagy nem (általában nem).
36

Csak úgy jött ide, hogy

eddig bírtam szó nélkül · 2012. Szep. 6. (Cs), 21.35
Csak úgy jött ide, hogy következetesen, mindenhol azt olvasom (fórumokon), hogy nem kell különösebben foglalkozni az optimalizálással, nem a CPU lesz a szűk keresztmetszet.
Én meg többször találkoztam olyan esettel, hogy bizony a CPU vagy a CPU is kevés volt.
37

Csak úgy jött ide, hogy

inf · 2012. Szep. 6. (Cs), 22.40
Csak úgy jött ide, hogy következetesen, mindenhol azt olvasom (fórumokon), hogy nem kell különösebben foglalkozni az optimalizálással, nem a CPU lesz a szűk keresztmetszet.


Ez így nem igaz. Clean code-ban sem azt írták, hogy nem kell foglalkozni vele, hanem azt, hogy először el kell készíteni a programot, és ha már készen van, csak utána optimalizálni, mert akkor derül ki, hogy hol van a szűk keresztmetszet. Itt is csak annyit állítottak, hogy általában az erőforrásokra várás az, ami lassít.