čtvrtek 19. června 2008

Programování v XML - špagety kód na druhou

Máte ještě nějakou část aplikace, která by nepoužívala XML? Já jich moc nenajdu. Všechno v pořádku, pokud XML používáte na správném místě a k správným účelům. Chraň vás ovšem ruka páně, pakliže začnete XML používat k věcem, na které nebylo navrženo. Asi nejtragičtějším příkladem špatného použití XML je zápis nějakého algoritmu – prostě k programování. Znáte Ant? Každý zná Ant, tak proč se ptám že.

Ant - jednoduchá myšlenka, buildovací nástroj, to co chceš popíšeš v XML.Problém je, když potřebujete dělat jenom trochu složitější konstrukty. Netrvá to moc dlouho a člověk sklouzne k tomu, že najednou tu potřebuje podmínku, tu změnu proměnné a tu nějaký cyklus. Jak to potom vypadá, ilustruje následující kód.


<target name="foo">
  <foreach param="jarName" target="doSomething" inheritall="true">
    <path>
      <dirset dir="${some.dir}" includes="**/*.jar"/>
    </path>
  </foreach>
</target>   
   
<target name="doSomething">
  <if>
    <contains string="${jarName}" substring="hibernate" casesensitive="false" />
    <then>            
      <!-- do something  with Hibernate JAR -->
    </then>
    <else>
      <!-- do something else --> 
    </else>
  </if>
</target>             
     
    

Teď si představte, že máte desítky, stovky kilobajtů podobného kódu. Řekl jsem kódu, programového kódu. Bohužel XML nebylo vymyšleno k zápisu programu, takže jediné co vám IDE nabídne, je jeho validace. Jsme sice v roce 2008, ale zapomeňte na debugování, zvýrazňování syntaxe a nebo nějaký refaktor. Proto vám po čase, pokud se rozhodnete programovat v XML, zbude jedna velká koule špaget, s kterou již nikdo nikdy nic neudělá.

Z velké části jsem napsal v XML resp. Antu instalační proces našeho produktu a mechanismus pro jeho rozšiřování. Dnes to považuji za velkou, ba co více, obrovskou kardinální chybu. Jediná výhoda je, že každý zná Ant. Takže po mě může přijít další člověk a po něm další, který dokáže udělat to, co potřebuje. Ve své podstatě nabalí další vrstvu špaget.

Moje lekce, kterou jsem si odnesl: XML není programovací jazyk. Nelze efektivně spravovat a proto, pokud jej použijete na popis algoritmů vašich programů, pak dříve nebo později budete mít v ruce tuny textu, které budete moci tak maximálně vyhodit.

Dobře, dost bylo střelby do vlastních řad. Jak bych to udělal dnes, kdybych mohl začít znovu. V ruce potřebuji mít něco, co mi umožní se soustředit na danou problematiku (např. kopírování, mazání, přejmenování, archivace souborů, textové nahrazení v souborů, XSLT transformace) a zároveň budu moci využít sílu programovacího jazyku (konstrukty - podmínky, cykly, rekurzivní volání) a podpory v IDE (debugování, zvýrazňování syntaxe, refaktoring).

Z toho mi vychází, že bych vytvořil vlastní DSL a nebo v uvozovkách DSL, která by mi umožnila efektivně se vyjádřit v daném kontextu. Budu ilustrovat následujícím kódem, který je přepisem výše uvedeného XML.

    
someDir.eachFileRecurse() { f ->    
    if(f.nameContains("hibernate") {
      //do something with hibernate
    } else {
      //do something else
    }
}
    
    

Tohle je snippet zapsaný v programovacím jazyku Groovy, který se dá mimo jiné použít pro tvorbu vlastní DSL. Samozřejmě mohl bych použít třeba Ruby, které by mohlo někomu připadat ještě jako lepší volba pro DSL. Každopádně sví ke svému. S Groovy bych získal přesně ty vlastnosti programovacího jazyku, které bych potřeboval a o kterých jsem se zmínil. Díky DSL ušité na míru pro daný problém bych umožnil daleko lepší vyjádření daného algoritmu.

Neudělejte stejnou chybu jako já, používejte technologie na to, k čemu byly určené a nikdy pro nic jiného.