úterý 28. října 2008

Eclipse tipy a triky: statické importy

Kolikrát jen už jsem napsal při psaní testů import static org.junit.Assert.*, abych pak mohl někde v testovací metodě napsat assertThat a nadávat si, že ještě musím naimportovat další statické metody. Samozřejmě to jde mnohem jednodušeji. Eclipse umožňuje přidat si metody předdefinovaných typů do content assist a ty potom nabízet aniž by byl typ v dané třídě naimportován. Při jejich použití se pak import automaticky nadeklaruje v dané třídě.

Postup je následující: Window >> Preferences >> Java >> Editor >> Content assist >> Favorites. Favorites menu nabízí přidání celého typu, resp. všech jeho statických metod viz tlačítko New Type, a nebo pouze vybraných metod viz tlačítko New Member.

pondělí 27. října 2008

Problém "Božského objektu"

Setkal jsem s ním snad v každé aplikaci, ale teprve teď jsem proto našel ten správný výraz - God object.

a God object is an object that knows too much or does too much

Mluvím o objektu, který plní stěžejní úlohu v celé aplikaci, něco jako centrální mozek lidstva ze seriálu Návštěvníci. Problém tohoto objektu je v tom, že neustále bobtná, výsledkem je, že máme interface s dvaceti a více metodami, což jednoduše nepřidá na přehlednosti našeho API a to už ani nemluvím o jeho implementaci.

To, že v aplikaci existuje nějaká business fasáda, která zastřešuje vícero operací je myslím v pořádku. To co většinou nebývá v pořádku je jakým způsobem je tato fasáda vytvořena a především naimplementována. Pomůžeme si praktickým příkladem.

public interface ObjednavkovaSluzba {
    public void vytvorObjednavku(Objednavka objednavka);
    public void smazObjednavku(Objednavka objednavka);
    public void aktualizujObjednavku(Objednavka objednavka);
    public Objednavka nactiObjednavku(Serializable identifikator);
    
    public void zpracujObjednavku(Serializable identifikator);
    public void zrusObjednavku(Serializable identifikator);   
}    

Jak je vidět z rozhraní, míchají se nám tam dvě odpovědnosti (většinou to bývá i více odpovědností nežli dvě). Jednak samotné CRUD (Create, Read, Update, Delete) operace pro vytvoření objednávky a jednak operace pro zpracování objednávky. Logika věci nám velí rozhraní roztrhnout, ale jak to udělat, aby zde byla stále možnost jednoho centralizovaného rozhraní pro práci s objednávkami.

Je to velice prosté. Opravdu to roztrhneme na dvě rozhraní podle odpovědností, ale rozhraní ObjednavkovaSluzba zachováme. A zachováme ho tak, že bude složením právě těchto dvou rozhraní.

public interface CRUDOperace {
    public void vytvorObjednavku(Objednavka objednavka);
    public void smazObjednavku(Objednavka objednavka);
    public void aktualizujObjednavku(Objednavka objednavka);
    public Objednavka nactiObjednavku(Serializable identifikator);          
}   

public interface ProcesniOperace {    
    public void zpracujObjednavku(Serializable identifikator);
    public void zrusObjednavku(Serializable identifikator);   
}  
 
public interface ObjednavkovaSluzba extends CRUDOperace, ProcesniOperace {
       
}        

Díky tomuto roztržení umožníme klientům využít nejen různé pohledy na jednu fasádu (CRUD, procesní operace a nebo celek), ale umožníme mít implementaci náležející plně dané odpovědnosti. Výslednou funkcionalitu můžeme dosáhnout například složením a delegací těchto implementací.

public class CRUDOperaceImpl implements CRUDOperace {
  //...implementace vynechána
}    

public class ProcesniOperaceImpl implements ProcesniOperace {
  //...implementace vynechána
}

public class ObjednavkovaSluzbaImpl implements ObjednavkovaSluzba  {
  private CRUDOperace crudDelegate;
  private ProcesniOperace procesniDelegate;
  
  public void vytvorObjednavku(Objednavka objednavka) {
      crudDelegate.vytvorObjednavku(objednavka);       
  }  
  
  public Objednavka nactiObjednavku(Serializable identifikator) {
      procesniDelegate.nactiObjednavku(identifikator);
  
  
  //...zbytek vynechán

Tímto velice jednoduchým cvičením jsme náš Božský objekt dekomponovali na menší části, které můžeme lépe spravovat, ale zároveň jsme zachovali jednotné rozhraní, které zaštiťuje práci s centrální funkcionalitou. Takto zrefaktorované rozhraní je navíc pro klienty API zpětně kompatibilní, takže se nemusíme obávat, že bychom něco rozbili.

neděle 26. října 2008

Java SE 6 Update 10 venku

Po roce čekání a více než miliónu stažení (viz Java SE 6 Update 10 is out but what does it deliver?) beta verze je venku dlouho očekávaný update číslo deset.

Podle označení by se zdálo, že se jedná pouze o fix pack, nicméně seznam úprav odpovídá spíše pořádnému třesku. Nejzásadnější změnou je nový plug-in systém, který umožňuje lepší běh a deployment appletů a to navíc v hybridním módu, kdy je možné běžící applet přetáhnout na desktop a provozovat jako klasickou desktopovou aplikaci.

  • Improved reliability. The JVM running the applet is isolated from the web browser at the operating system level. If something should go wrong while running the applet, or if an uncooperative applet refuses to shut down, the new Java Plug-In detects and handles the error condition gracefully; the web browser is unaffected.
  • Built-in JNLP support. The new plug-in offers the capability to launch applets directly from JNLP files, unifying deployment of Java content both in the browser and out of the browser (via Java Web Start). Developers can now reuse JNLP extensions for advanced functionality including the JavaFX run-time libraries, 3D graphics via OpenGL, and planetary-scale terrain visualization within applets. Applets can now access JNLP APIs for persistent data storage, local file system access, and other useful functionality from sandboxed code.
  • Per-applet command-line arguments. JVM command-line arguments may be specified on a per-applet basis, providing fine-grained control over options such as the heap size and Java 2D hardware acceleration features. JNLP-launched applets simply incorporate the command-line arguments and/or system properties into the JNLP file. Old-style applets can embed these arguments in the HTML of the web page.
  • Multiple JRE version support. Each individual applet instance may request a different JRE version on which to run. This feature is designed for enterprise customers which prefer to qualify their applets against either a particular JRE version or a particular JRE family. Both selection of a specific JRE version, or any in a particular family, are supported in the new plug-in.
  • Improved Java/JavaScript communication. The bridge between the JavaScript engine in the web browser and the Java programming language has been completely reimplemented. The new implementation is backward-compatible and features improved reliability, performance and cross-browser portability, for both Java calling JavaScript as well as JavaScript calling Java. Formerly Mozilla-specific "LiveConnect" functionality, such as the ability to call static Java methods, instantiate new Java objects and reference third-party packages from JavaScript, is now available in all browsers.
  • Improved user experience. The new Java Plug-In starts applets in the background, so the web browser always remains responsive. Applets appear on the web page as they become ready to run.
  • Improved applet lifecycle management. Calls to the applet lifecycle methods init, start, stop, and destroy are more deterministic and cross-browser behavior has been improved. The applet class loader cache and the legacy applet lifecycle, required for backward compatibility, are fully supported and the behavior of both has been improved.
  • Better large heap support. Historically, the maximum heap size that could be specified for applets via the Java Control Panel has been limited. This limitation is fixed in the new Java Plug-In; applets can now utilize as much heap space as command-line applications.
  • Better Windows Vista support. Signed applets running in Protected Mode Internet Explorer on Microsoft's Windows Vista now have the same privileges as normal user applications, eliminating a portability barrier to this platform.

Nuže předmostí pro JavaFX je položeno, otázka zní není to pozdě? Technologie appletů totiž žehrá na to, že na ní Sun dlouhou dobu kašlal a ta se tak trochu zkompromitovala sama. Uvidíme jestli tato resuscitacek něčemu povede.