A Case Study on Event-Driven Web
             Applications and View Modularization
             Christopher Rogers
             Naver Japan
             Search Service Development




Friday, July 23, 2010
紹介


                   Naver Japan 統合検索のフロント開発

                        検索結果取得、HTML出力

                        主に Java (たまに C/C++)




Friday, July 23, 2010
ケース1
             検索結果の読み込み




Friday, July 23, 2010
検索結果の読み込み

                   問題

                        多くのリソースからデータを読み込む必要がある。

                        統合検索ページは現在 38ヶ所からデータを読み込んでいる

                        依存性もある(並行で読み込めないデータ)



Friday, July 23, 2010
ひとつの解決策:同期読込

             dataSource1.load(); // 終わるまで待機
             // データ処理/HTML 出力
                                                 依存性
             dataSource2.load();
             // ...
             dataSource3.load(dataSource1.isNews);
             // ...




Friday, July 23, 2010
問題点

                   依存性がなくても他の読み込みを待機させる。

                        一部データソースの障害発生時、それ以降の読み込みを遅ら
                        せることになる。

                        全般的にページのロード時間が遅くなる。

                   接続が増えるほど管理性が低下。



Friday, July 23, 2010
イベント駆動(非同期読み込み)
             dataSource1.fetch();
             dataSource2.fetch();
             dataSource1.wait();
             dataSource3.fetch(dataSource1.isNews);
             // dataSource1 のデータを処理...
             dataSource2.wait();
             // ...


Friday, July 23, 2010
イベント駆動+”定義指向”
                   <chain>
                       <invoke refid=”dataSource1”/>
                       <chain>
                            <invoke refid=”dataSource3”/>
                       </chain>
                   </chain>
                   <chain>
                       <invoke refid=”dataSource2”/>
                   </chain>


Friday, July 23, 2010
イベント駆動+”定義指向”
                   <chain>
                       <invoke refid=”dataSource1”/>
                       <chain>
                            <invoke refid=”dataSource3”/>
                       </chain>
                   </chain>
                   <chain>
                       <invoke refid=”dataSource2”/>
                   </chain>


Friday, July 23, 2010
イベント駆動+”定義指向”
                   <chain>
                       <invoke refid=”dataSource1”/>
                       <chain>
                            <invoke refid=”dataSource3”/>
                       </chain>
                   </chain>
                   <chain>
                       <invoke refid=”dataSource2”/>
                   </chain>


Friday, July 23, 2010
イベント駆動+”定義指向”
                   <chain>
                       <invoke refid=”dataSource1”/>
                       <chain>
                            <invoke refid=”dataSource3”/>
                       </chain>
                   </chain>
                   <chain>
                       <invoke refid=”dataSource2”/>
                   </chain>


Friday, July 23, 2010
イベント駆動+”定義指向”
                   <chain>
                       <invoke refid=”dataSource1”/>
                       <chain>
                            <invoke refid=”dataSource3”/>
                       </chain>
                   </chain>
                   <chain>
                       <invoke refid=”dataSource2”/>
                   </chain>


Friday, July 23, 2010
イベント駆動+”定義指向”
                   <chain>
                       <invoke refid=”dataSource1”/>
                       <chain>
                            <invoke refid=”dataSource3”/>
                       </chain>
                   </chain>
                   <chain>
                       <invoke refid=”dataSource2”/>
                   </chain>


Friday, July 23, 2010
イベント駆動+“定義指向”
                   長所

                        「関心の分離」(http://ja.wikipedia.org/wiki/関心の分離)

                         同期コードとビジネス
                         ロジックの分離

                        一目で依存関係がわかる

                        管理性


Friday, July 23, 2010
ケース2
             HTML 出力 (View Layer)




Friday, July 23, 2010
ビュー

                   一般的には...

                        テストしにくい

                        リファクタリングは難しい

                        再利用しにくい



Friday, July 23, 2010
ビュー
                   JSP
                   直感的でわかりやすい

                   短所

                        データ共有(変数とスコープ管理が困難)

                        複雑なロジックはコードに災害を起こす

                         カスタムタグでは限界がある


Friday, July 23, 2010
ビュー

                   目標

                        コード重複の削減

                        再利用できるコンポーネントを作る

                        コード可読性の向上



Friday, July 23, 2010
Wicket
                   ビュー部分を抽出して統合検索のフレームワークに導入。

                   長所

                        HTML とビューのロジックが分離されている。

                        Pure Java™ とソフトウェアデザインパターンが使えて、主に
                        Template Method と Abstract Factory を実用化。

                        HTML パーサーまでいろいろ拡張できる。


Friday, July 23, 2010
Wicket

                   短所

                        Java の面倒なところ

                         文字列結合

                         無名インナークラスが冗長



Friday, July 23, 2010
<div id=”header”>

                        <wicket:container wicket:id=”searchPanel”/>

                        <wicket:container wicket:id=”tabs”/>

             </div>

             <div id=”contents”>

                        <wicket:child/>

             </div>

             <wicket:container wicket:id=”footer”/>



Friday, July 23, 2010
<div id=”header”>

                        <wicket:container wicket:id=”searchPanel”/>

                        <wicket:container wicket:id=”tabs”/>

             </div>

             <div id=”contents”>

                        <wicket:child/>

             </div>

             <wicket:container wicket:id=”footer”/>



Friday, July 23, 2010
Template Method パターン
                   @Override protected void onBeforeRender() {
                       add(newSearchPanel(“searchPanel”));
                       add(newTabPanel(“tabs”));
                       add(newFooter(“footer”));
                   }
                   protected Component newSearchPanel(String id) {
                       return new SearchPanel(id);
                   }
                   protected abstract Component newFooter(String id);
                   protected Component newTabPanel(String id) {
                       return new TabPanel(id);
                   }
                   /* subclass */ @Override protected Component newTabPanel(String id) {
                       return new SpecialTabPanel(id).showOptions().hideSearchBox();
                   }




Friday, July 23, 2010
Friday, July 23, 2010

A Case Study On Event Driven Web Applications And View Modularization

  • 1.
    A Case Studyon Event-Driven Web Applications and View Modularization Christopher Rogers Naver Japan Search Service Development Friday, July 23, 2010
  • 2.
    紹介 Naver Japan 統合検索のフロント開発 検索結果取得、HTML出力 主に Java (たまに C/C++) Friday, July 23, 2010
  • 3.
    ケース1 検索結果の読み込み Friday, July 23, 2010
  • 4.
    検索結果の読み込み 問題 多くのリソースからデータを読み込む必要がある。 統合検索ページは現在 38ヶ所からデータを読み込んでいる 依存性もある(並行で読み込めないデータ) Friday, July 23, 2010
  • 5.
    ひとつの解決策:同期読込 dataSource1.load(); // 終わるまで待機 // データ処理/HTML 出力 依存性 dataSource2.load(); // ... dataSource3.load(dataSource1.isNews); // ... Friday, July 23, 2010
  • 6.
    問題点 依存性がなくても他の読み込みを待機させる。 一部データソースの障害発生時、それ以降の読み込みを遅ら せることになる。 全般的にページのロード時間が遅くなる。 接続が増えるほど管理性が低下。 Friday, July 23, 2010
  • 7.
    イベント駆動(非同期読み込み) dataSource1.fetch(); dataSource2.fetch(); dataSource1.wait(); dataSource3.fetch(dataSource1.isNews); // dataSource1 のデータを処理... dataSource2.wait(); // ... Friday, July 23, 2010
  • 8.
    イベント駆動+”定義指向” <chain> <invoke refid=”dataSource1”/> <chain> <invoke refid=”dataSource3”/> </chain> </chain> <chain> <invoke refid=”dataSource2”/> </chain> Friday, July 23, 2010
  • 9.
    イベント駆動+”定義指向” <chain> <invoke refid=”dataSource1”/> <chain> <invoke refid=”dataSource3”/> </chain> </chain> <chain> <invoke refid=”dataSource2”/> </chain> Friday, July 23, 2010
  • 10.
    イベント駆動+”定義指向” <chain> <invoke refid=”dataSource1”/> <chain> <invoke refid=”dataSource3”/> </chain> </chain> <chain> <invoke refid=”dataSource2”/> </chain> Friday, July 23, 2010
  • 11.
    イベント駆動+”定義指向” <chain> <invoke refid=”dataSource1”/> <chain> <invoke refid=”dataSource3”/> </chain> </chain> <chain> <invoke refid=”dataSource2”/> </chain> Friday, July 23, 2010
  • 12.
    イベント駆動+”定義指向” <chain> <invoke refid=”dataSource1”/> <chain> <invoke refid=”dataSource3”/> </chain> </chain> <chain> <invoke refid=”dataSource2”/> </chain> Friday, July 23, 2010
  • 13.
    イベント駆動+”定義指向” <chain> <invoke refid=”dataSource1”/> <chain> <invoke refid=”dataSource3”/> </chain> </chain> <chain> <invoke refid=”dataSource2”/> </chain> Friday, July 23, 2010
  • 14.
    イベント駆動+“定義指向” 長所 「関心の分離」(http://ja.wikipedia.org/wiki/関心の分離) 同期コードとビジネス ロジックの分離 一目で依存関係がわかる 管理性 Friday, July 23, 2010
  • 15.
    ケース2 HTML 出力 (View Layer) Friday, July 23, 2010
  • 16.
    ビュー 一般的には... テストしにくい リファクタリングは難しい 再利用しにくい Friday, July 23, 2010
  • 17.
    ビュー JSP 直感的でわかりやすい 短所 データ共有(変数とスコープ管理が困難) 複雑なロジックはコードに災害を起こす カスタムタグでは限界がある Friday, July 23, 2010
  • 18.
    ビュー 目標 コード重複の削減 再利用できるコンポーネントを作る コード可読性の向上 Friday, July 23, 2010
  • 19.
    Wicket ビュー部分を抽出して統合検索のフレームワークに導入。 長所 HTML とビューのロジックが分離されている。 Pure Java™ とソフトウェアデザインパターンが使えて、主に Template Method と Abstract Factory を実用化。 HTML パーサーまでいろいろ拡張できる。 Friday, July 23, 2010
  • 20.
    Wicket 短所 Java の面倒なところ 文字列結合 無名インナークラスが冗長 Friday, July 23, 2010
  • 21.
    <div id=”header”> <wicket:container wicket:id=”searchPanel”/> <wicket:container wicket:id=”tabs”/> </div> <div id=”contents”> <wicket:child/> </div> <wicket:container wicket:id=”footer”/> Friday, July 23, 2010
  • 22.
    <div id=”header”> <wicket:container wicket:id=”searchPanel”/> <wicket:container wicket:id=”tabs”/> </div> <div id=”contents”> <wicket:child/> </div> <wicket:container wicket:id=”footer”/> Friday, July 23, 2010
  • 23.
    Template Method パターン @Override protected void onBeforeRender() { add(newSearchPanel(“searchPanel”)); add(newTabPanel(“tabs”)); add(newFooter(“footer”)); } protected Component newSearchPanel(String id) { return new SearchPanel(id); } protected abstract Component newFooter(String id); protected Component newTabPanel(String id) { return new TabPanel(id); } /* subclass */ @Override protected Component newTabPanel(String id) { return new SpecialTabPanel(id).showOptions().hideSearchBox(); } Friday, July 23, 2010
  • 24.