Apr 1, 2011

Nepoužívané triedy smrdia

Stovky tried, desiatky mených priestorov, triedy s podobným menom, niekoľkokrát prepísané triedy a nahradené novými. Manažmentom zrušené celé časti aplikácií hnijúce na miestach, ktoré developeri zďaleka obchádzajú? Je čas opäť upratať ten bordel v projekte.

Začnime s nepoužívanými triedami. Ako ich zistiť? PMD je na túto úlohu prikrátke — vie zistiť len nepoužívané privátne funkcie.

Jono Spiro, chalan ktorý kedysi pracoval na mxml kompilátore, navrhuje použiť nedokumentovaný parameter kompilatora --keep-generated-signatures spolu s -incremental parametrom. Tato kombinácia vygeneruje signatúry všetkých tried do adresára generated-signatures.

Signatúry sú súbory (*.sig) vytvorené z verejných tried, ktoré obsahujú zoznam funkcií, atribútov, importov, metadát atď. a ktoré môžu mať závislosti na iných triedach. Ak sa teda signatúra pre niektorú z tried nevygeneruje, trieda sa nepoužíva. Rozdielom zoznamu signatúr a zoznamu tried budú nepoužívané triedy:

import os, fnmatch

def find_files(path, patterns=(".txt",)):
    found = []

    for root, dirs, files in os.walk(path):
        for pattern in patterns:
            for filename in fnmatch.filter(files, pattern):
                relative_path = root.split(path)[1]
                found.append(os.path.join(relative_path, filename))

    return found

def find_unused_classes():

    all_sources = find_files(r'e:\path\to\src\\', ('*.as','*.mxml'))
    sources = (file.replace(os.sep, '_') for file in all_sources)
    signatures = find_files(r'e:\path\to\src\generated-signatures\\', ('*.sig',))

    diff = []

    for source in sources:
        splitted = source.split('.')
        transformed = splitted[0]

        if splitted[1] == 'mxml':
            transformed += '-generated.sig'
        else:
            transformed += '.sig'

        if transformed not in signatures:
            print '', source
            diff.append(source)

    return diff

garbage = find_unused_classes()
Nov 28, 2010

Integračné peklo

Pripájam pár slajdov prezentovaných na novembrovom stretnutí AUG. Vtipnú as3 aplikáciu (SmileApp) sme priamo počas prednášky úspešne nasadili na hudsona.

Nov 14, 2010
Adobe UG Slovakia, meeting - 25.11.2010 - 17:00

Adobe UG Slovakia, meeting - 25.11.2010 - 17:00

Sep 9, 2010

CPD, Copy Paste Detector

Predošlý článok obsahoval krátke zhrnutie nástroja na detekciu špiny v kóde. Project Mess Detector (PMD) detekuje rôzne druhy špiny, od malej, cez stredne veľkú až po hrubú špinu. Jeho kolega Copy Paste Detector (CPD) je tiež kus dobrého nástroja. CPD detekuje duplicitný kód [1].

Čo je to duplicitný kód?

Úsek kódu, ktorého výskyt v množine zdrojového kódu je väčší ako jedna nazývame duplicitný kód. Názory sa rôznia [2] avšak vo všeobecnosti sa duplicitný kód považuje za nežiadúci [3].

copy paste code means copy paste bugs
neznámy autor

Ako vzniká duplicitný kód?

  • Copy and paste programming - spôsob programovania, ktorý za sebou zanecháva často sa opakujúci kus kódu vytvorený technikou Copy/Paste.
  • Vývojár nezávisle a nič netušiac napíše kód podobný tomu, ktorý už niekde v zdrojovom kóde existuje.
  • Plagiátorstvo, kedy sa kód kopíruje bez autorovho súhlasu [4].

Aké sú dôsledky?

Zrozumiteľnosť kódu: kopírovanie zvyčajne vytvára dlhé, opakujúce sa úseky kódu, ktoré sa líšia pár riadkami alebo len pár znakmi. Pochopiť takýto kód je časovo a kapacitne náročnejšie.

Maskovanie skutočného účelu: opakovanie prevažne identických častí kódu skrýva rozdiely medzi nimi a teda ich skutočný účel. Často sa rozdiel nachádza napr. len v hodnote parametra.

Údržba kódu: každý duplikát musí byť aktualizovaný zvlášť, čo má za následok zvýšenie výdavkov za udržiavanie softvéru. Pri najlepšom, čas údržby kódu a testovania je vynásobený počtom duplikátov. V najhoršom prípade prehliadneme niektoré duplikáty a chyby ktoré by mali byť opravené hnijú na svojich miestach mesiace až roky [4].

duplicitný kód = cesta do pekiel
Juraj Michálek

FlexCPD

Copy/Paste detektor a FlexPMD slovník tvoria spolu nástroj FlexCPD určený na detekciu duplicitného as/mxml kódu. FlexCPD sa podobne ako FlexPMD spúšťa cez príkazový riadok, ako Ant target, Maven alebo priamo z IDE (Eclipse) [5]. FlexPMD a FlexCPD tvoria skvelú dvojku pri pátraní po menej kvalitnom či duplicitnom kóde.

Spustenie FlexCPD z IDE.Spustenie FlexCPD z IDE.

Výstupom FlexCPD je XML súbor interpretovaný či už cez IDE alebo pomocou nástroja kontinuálnej integrácie.

Výsledky vyhľadávania duplicitného kódu.Výsledky vyhľadávania duplicitného kódu.

Historický report duplicitného kódu pomocou kontinuálnej integrácieHistorický report duplicitného kódu pomocou kontinuálnej integrácie (hudson)

Citácie:

Literatúra:

Pre fajnšmekrov:

Aug 4, 2010

PMD = Project Mess Detector

Napísať a udržiavať kus softvéru je náročná úloha. Každý vývojár zvykne mimovoľne robiť chyby. Zvyčajne sú to malé preklepy, ktoré odchytí kompilér, avšak ostatné chyby možu ostať neodhalené až do momentu nasadenia aplikácie v produkčnom prostredí. Okrem následkov zlyhania aplikácie, softvérové defekty nesú so sebou aj podstatné finančné náklady na svoje odstránenie. Jednou z možností ako predísť defektom je včas ich odhaliť.

PMD je nástroj, ktorý skenuje zdrojový kód a hľadá v ňom možné problémy ako:

  • nevhodný dizajn - prázdne try—catch—finaly/switch bloky …
  • mŕtvy kód - nepoužívané lokálne premenné, parametre a privátne metódy …
  • neoptimálny kód - nové inštancie v slučkách …
  • prekomplikované výrazy - nepotrebné if výrazy, vnorené for cykly …
  • duplicitný kód - copy-paste kód znamená copy-paste bugs

Podľa tvorcov PMD skratka nemá žiadny význam, ale minimálne jedna výstižná sa nájde: “Project Mess Detector”.

Prečo používať PMD?

  • S PMD dokážeme posúdiť kvalitu kódu na základe jednoduchých pravidiel. Ako povedal Tom DeMarco, “nevieme kontrolovať to čo nevieme merať”.
  • Nielen junior vývojári majú svoje drobné “zlozvyky”. PMD včas odhalí nevhodný dizajn kódu a pomože nám túto úlohu zautomatizovať.
  • PMD vie či vývojári dodržiavajú interné code guidelines a dohodnuté štandardy.

FlexPMD

FlexPMD je klon PMD určený pre ActionScript 3 a MXML. Okrem všeobecných PMD pravidiel obsahuje pravidlá špecifické pre Flex SDK, Cairngorm, AsDocs, MXML, Bindings, CSS, Events atď. FlexPMD sa dá spustiť napríklad z príkazovej riadky, Ant skriptu, Eclipse, z Mac OSX Automator alebo Maven-om (http://opensource.adobe.com/wiki/display/flexpmd/How+to+invoke+FlexPMD). Výsledný report s porušeniami pravidiel (súbor vo formáte XML) sa dá interpretovať viacerými spôsobmi (http://opensource.adobe.com/wiki/display/flexpmd/How+to+interpret+results):

priamo v Eclipse prostredí,

v Hudson-e

alebo v prehliadači (http://opensource.adobe.com/svn/opensource/flexpmd/bin/flex-pmd-violations-viewer.html).

Best practices

Zvoľte si pravidlá, ktoré vám vyhovujú

Povolenie všetkých pravidiel spôsobí vytvorenie obrovského reportu, z ktorého veľké množstvo porušení aj tak nebude dôležitých. Prehrabávanie sa tisíckami riadkov reportu pre pár výnimiek asi čoskoro prestane baviť. Začnite s bežnými kategóriami pravidiel a neskôr pridávajte ďalšie. Šikovný nástroj od Adobe vypľuje naklikaný RuleSet: http://opensource.adobe.com/svn/opensource/flexpmd/bin/flex-pmd-ruleset-creator.html.

Používajte IDE plugin

Používať PMD v IDE je príjemnešie ako prepínať medzi HTML reportom a IDE tam a späť. Vo väčšine IDE, klik na výnimku v reporte spôsobí skok na konkrétny problémový riadok v kóde.

Nesnažte sa dosiahnúť 0 výnimiek

Snahou nie je dosiahnúť prázdny report, ten má len Chuck Norris. Vždy budú existovať v projekte výnimky, ktoré pravidlá porušia.

Literatúra:

Jul 30, 2010

Jednotné nastavenia mxmlc kompilátora

Nastaviť mxmlc kompilátor pri novom projekte na prvý krát správne sa mi ešte nikdy nepodarilo. Vždy chýbal nejaký parameter alebo som jeho hodnotu zle zapísal.

Kedysi moje nastavenie vyzeralo nejako takto:

-locale en_US

Po čase sa rozrástlo na:

-locale en_US -keep-generated-actionscript -incremental -optimize=false 
-keep-as3-metadata+=Collaborative,Keywords 
-define=APPLICATION::debug,true -define=APPLICATION::release,false

Vynásobím si počet zmien za rok krát počet vývojových strojov, prirátam jeden integračný server a dostanem desiatky úprav kompilačných argumentov, desiatky duplicitných informácií, ktoré sú roztrúsené po celom development department. Každá ďalšia zmena mi pripomína, že musím napísať e-mail s oznamom o zmene, že na polovici strojov to budem musieť prísť upraviť osobne a ešte sa prihlásiť na server, nájsť všetky miesta v ant-ových skriptoch kde sa nastavujú ďalšie kompilačné parametre (unit-testy, mapy pokrytia …). Pri najlepšom je to pár hodín roboty.

Našťastie sa to celé dá spríjemniť na jeden jediný svn commit a v budúcnosti už nemusíme nastavovať každý stroj zvlášť, základné nastavenia mxmlc budú konzistentné a my ostaneme DRY.

  1. Vytvoríme app-config.xml. Súbor kopíruje štruktúru východzieho konfiguračného súboru sdk/3.5.0.12683a/frameworks/flex-config.xml avšak nemusí byť kompletný a stačí ak bude obsahovať len nastavenia, ktoré chceme zmeniť.
<flex-config>
    <compiler>
        <define>
            <name>APPLICATION::debug</name>
            <value>false</value>
        </define>
        <define>
            <name>APPLICATION::release</name>
            <value>true</value>
        </define>
        <keep-as3-metadata>
            <name>Bindable</name>
            <name>Managed</name>
            <name>ChangeEvent</name>
            <name>NonCommittingChangeEvent</name>
            <name>Transient</name>
            <name>Collaborative</name>
            <name>Keywords</name>
        </keep-as3-metadata>
        <keep-generated-actionscript>true</keep-generated-actionscript>
        <optimize>false</optimize>
        <incremental>true</incremental>
    </compiler>
</flex-config>
  1. Necháme si prejsť mráz po chrbte a posledný krát nastavíme na všetkých strojoch kompilačné argumenty vývojového prostredia:
    -load-config+=app-config.xml

  2. Pri budúcej zmene kompilačných argumentov stačí editovať xml súbor a zmeny rozdistribuovať cez svn.

Literatúra:

Jul 27, 2010

Flash/Flex Builder shortcuts

Holly Schinsky zverejnila na svojom blogu skvelý zoznam skratiek a typov pre urýchlenie práce s Flash Builderom. Keďže čas sú peniaze, pridávam ďalšie urýchlovače. Niektoré z nich fungujú aj pre Flex Builder 3. V priloženom PDF sa nachádzajú verzie skratiek pre Mac aj Windows. Stačí vytlačiť na A4, preložiť na polovicu a prilepiť na monitor.

Tlačená forma:

  • stiahnúť PDF
  • vytlačiť na A4
  • preložiť na polovicu
  • prilepiť na monitor
Apr 1, 2010

Kontinuálna integrácia Flex/AIR projektov

Na poslednom stretnutí AUG Slovakia sme sa medzi iným rozprávali aj o postupoch, možnostiach a výhodách kontinuálnej integrácie Flex a AIR projektov.

Spoločnosť sinusgear.com poskytla vzorovému projektu hosting a bezkonkurenčnú podporu.

Mar 24, 2010

Adobe User Group Slovakia Stretnutie - 25. Marec, 2010

Stretnutie zamerane na Adobe Flash Platform (Flash/Flex/AIR) a novinky v tejto oblasti, ktore na nas Adobe chysta v nasledujucich tyzdnoch a mesiacoch: Flash Player 10.1, AIR 2.0, Flex 4, Flash Builder 4, atd.

Čas: 25. Marec, 2010 od 18:00 do 20:00
Miesto: Galvaniho 17/A, Bratislava

Viac na stránke AUG Slovakia: http://groups.adobe.com/posts/980dd04221

Jul 7, 2009

Začíname s Picasa Web API (II)

V tejto časti si povieme bližšie o knižnici Picasa Flash API, ako ju použiť vo Flash-ových projektoch a ukážeme si krátky príklad slideshow otagovaných obrázkov z vášho Picasa Web účtu.

V prvej časti seriálu o Picasa Web API sme si priblížili pojmy služba Picasa Web Albums a jej rozhranie Picasa Web Albums Data API. Povedali sme si čo je to Picasa Flash API a kde takéto API zohnať, čo všetko treba spraviť pre úspešný response zo strany Picasa Web API a ako nám to Picasa Flash API umožní dosiahnúť v kratšom čase a s menšou námahou.

Stiahnúť

Najčerstvejšia verzia Picasa Flash API sa vždy nachádza v svn. Zo zdrojových súborov je pre každú významnú revíziu vytvorená swc knižnica, ktorá sa dá stiahnúť na adrese http://code.google.com/p/picasaflashapi/downloads/list

Nainštalovať

Použitie knižnice sa líši od Flash verzie. Pre Flash CS3, treba knižnicu skopírovať do “Components” zložky:

  • V systéme Windows: C:\Program Files\Adobe\Adobe Flash CS3\language\Configuration\Components
  • Pre Mac: /Applications/Adobe Flash CS3/Configuration/Components

Po nakopírovaní knižnice do zložky ju vo Flash CS3 stačí presunúť z Components okna do Library a triedy budú k dispozícii.

Flash CS4 je inteligentnejší a dovoľuje nám zadefinovať knižnicu v záložke Library Path v Publish Settings nasledovne:

Flash CS4 Publish Settings.

Hotovo. Knižnica je vo Flash-i.

Použiť

Našou nasledujúcou úlohou bude vytvoriť jednoduchú aplikáciu, ktorá bude zobrazovať množinu fotografií umiestnených a označkovaných v Picasa Web galérii. Zobrazovanie fotografií by malo byť manuálne a automatické. Ak je k dispozícii názov fotografie, chceme ho zobraziť tiež. To aké fotografie chceme zobrazovať by sa malo dať definovať cez FlashVars aby sme mohli aplikáciu použiť na viacerých miestach s rôznymi značkami.

Užívateľské rozhranie je na vás. Ja som použil štandardné Flash komponenty. UILoader v tandeme s ProgressBar-om bola pre mňa najrýchlejšia možnosť ako dostať do aplikácie obrázok s feedback-om sťahovaných dát. Dva Illustrator-om naskinované Button-y slúžia ako “Play” a “Next”. Pre názov obrázku som použil klasický TextField s embednutým písmom.

Flash CS3 Scene with components.

Kvôli prehľadnosti uvediem len časti kódu týkajúce sa dát.

var service : PicasaService = new PicasaService();
    service.imgmax = "400";`

Vytvoríme inštanciu Picasa služby s tým, že maximálna veľkosť obrázkov, ktoré budeme ďalej načítavať bude 400 pixelov. Všetky dostupné vlastnosti služby a ich hodnoty nájdete v asdoc.

var loader : UILoader;
var entries : Array;
var responder : PicasaResponder = service.albums.list_by_tag(fv.user || "thisispinkfu", fv.tag || "diana");
    responder.addEventListener(PicasaDataEvent.DATA, serviceComplete_Handler, false, 0, true);
    responder.addEventListener(ErrorEvent.ERROR, serviceError_Handler, false, 0, true);

Zadefinujeme pole “entries”, ktoré bude naplnené po úspešnej odpovedi a v prípade, že odpoveď obsahuje jeden a viac obrázkov. Volanie metódy list_by_tag(username, tag) na službe nám vráti objekt typu PicasaResponder, ktorý vysiela servisné udalosti.

function serviceComplete_Handler(evt : PicasaDataEvent) : void
{
    // naplnime entires
    entries = evt.data.entries.concat([]);

    if(entries.length > 0)
    {
         // spustime tahanie obrazkov
         loadNextEntry();
    } 
    else
    {
         // nemame ziadne obrazky (neexistujuci tag alebo uzivatel)
         cmp_label.text = "Zero entries...";
    }
}

Ak dostaneme úspešnú odpoveď z Picasa Web Data API, naplníme pole entries objektmi, ktoré pre nás automaticky vytvorí Picasa Flash API. Ak sa v poli nachádza aspoň jeden objekt, zavoláme funkciu loadNextEntry(). V opačnom prípade nastala zrejme chyba, resp. značka, ktorú sme uviedli vo volaní metódy list_by_tag neexistuje, resp. žiadny obrázok v našej galérii nebol označkovaný.

function serviceError_Handler(evt : ErrorEvent) : void
{
    cmp_label.text = "Error: " + evt.text;
}

Ak služba nedostala úspešnú odpoveď, napr. zadaný užívateľ neexistuje, zobrazíme feedback o chybe.

function loadNextEntry(evt : Event = null) : void
{
    var url : String = entries[entry].media.content.url;// url obrazku
    var lbl : String = entries[entry].summary; // nazov obrazku 

    cmp_label.text = lbl != null ? lbl : ""; // cmp_label je text field

    // vytvorime instanciu UILoader-a a pridame na Stage
    loader = new UILoader();
    loader.width = 400;
    loader.height = 400;
    loader.addEventListener(Event.COMPLETE, imageComplete_Handler, false, 0, true);
    loader.addEventListener(IOErrorEvent.IO_ERROR, imageError_Handler, false, 0, true);
    loaders.addChild(loader);

    // spustime cucanie
    loader.load(new URLRequest(url));
}

Funkcia loadNextEntry nahrá ďalší obrázok v poradí. Extrahuje adresu obrázka a jeho názov z objektu v poli entries, vytvorí novú inštanciu triedy UILoader a zapíše “complete” a “ioError” event listenery.

function imageComplete_Handler(evt : Event) : void
{
    // spustime napr. timer
}

Po úspešnom stiahnutí obrázka sa zavolá funkcia imageComplete_Handler, do ktorej umiestnime napríklad prezentačný kód, ktorý spustí slideshow.

function imageError_Handler(evt : IOErrorEvent) : void
{
    cmp_label.text = "Error: " + evt.text;
}

V prípade, že nastala chyba pri sťahovaní obrázka, zavolá sa funkcia imageError_Handler, ktorá zobrazí feedback o chybe.

function get fv() : Object
{
    return Object(LoaderInfo(this.loaderInfo).parameters);
}

Helper funkcia fv() vracia objekt s FlashVars. Umožňuje nám opýtať sa napr. na hodnotu premennej user definovanej cez flashVars v html <object/> alebo <embed/> tagu.

Nasadiť

Výsledok bude vyzerať približne takto:

Zdrojové súbory (Flash CS4) môžte stiahnuť z http://picasaflashapi.googlecode.com/svn/trunk/docs/tutorials/Flash_Slideshow/zip/Flash_Slideshow.zip

Kam ďalej

V tejto časti seriálu o knižnici PicasaFlashApi a spol. sme si ukázali ako jednoducho zobraziť otagované obrázky vo Flash aplikácii. Na pozadí jedného volania funkcie service.albums.list_by_tag(user, tag) nám knižnica PicasaFlashAPI poskladala request, odoslala, čakala na odpoveď druhej strany, preparsovala a vyhodnotila odpoveď a nakoniec vrátila pole objektov. S PicasaFlashAPI je možné toho spraviť oveľa viac a dokonca ešte jednoduchšie, o tom však neskôr.

Linky na ďalšie zdroje:

Navigate
« To the past Page 1 of 2
About
Subscribe via RSS.