サーバサイドJavaアンチパターン(Bruce A. Tate)
書籍情報
- 著者:Bruce A. Tate(著), トップスタジオ(訳)
- 発行日:2003-03-24
- ISBN:9784822281571
書籍目次
- まえがき
- 目次
- 序文
- 謝辞
- 本書について
- 本書の構成
- 本書の使い方
- 本書の対象読者
- ソースコード
- 表記規則
- オンラインの情報源
- 第1部 基礎
- 第1章 苦い失敗談
- 1.1 自由落下するJava開発
- 1.1.1 生活の中のアンチパターン
- 1.2 成功例を活用するデザインパターン
- 1.2.1 オンラインの参考資料
- 1.2.2 パターン記述言語としてのUML
- 1.3 失敗例から学ぶアンチパターン
- 1.3.1 よく知られているアンチパターンの例
- 1.3.2 実践の中のアンチパターン
- 1.3.3 アンチパターンの参考資料
- 1.4 昔からあるアンチパターン
- 1.4.1 他の産業界から学ぶ
- 1.4.2 アンチパターンの発見
- 1.4.3 アンチパターンのリファクタリング
- 1.5 なぜBitter Javaか
- 1.5.1 本書のアプローチ
- 1.5.2 本書で使うツール
- 1.5.3 本書の構成
- 1.5.4 本書の読者
- 1.6 将来
- 1.1 自由落下するJava開発
- 第2章 苦い眺め
- 2.1 アンチパターンを生み育てる肥沃な土壌
- 2.1.1 階層化の利点
- 2.1.2 階層化の欠点
- 2.2 インターネットの技術
- 2.2.1 インターネットのトポロジーがアプリケーションに与える影響
- 2.2.2 エンタープライズ層におけるセキュリティ確保とそのオーバーヘッド
- 2.2.3 インターネットを支える標準
- 2.2.4 通信の基礎を提供する TCP とIP
- 2.2.5 アプリケーションレベルの転送を提供するHTTP
- 2.2.6 HTMLとXML
- 2.2.7 ミニアンチパターン: Too Many Web Page Items
- 2.3 オブジェクトテクノロジーとアンチパターン
- 2.3.1 カプセル化: 変更の局在化.
- 2.3.2 継承: 共通特性のパッケージ化
- 2.3.3 ポリモルフィズム: 再利用のための柔軟な方法
- 2.3.4 ミニアンチパターン: Excessive Layering
- 2.3.5 Javaの時代
- 2.4 アンチパターンを解消するJava技術
- 2.5 ウォーターフォール開発法に伴う主要な問題
- 2.5.1 反復型開発
- 2.5.2 ミニアンチパターン: Incomplete Process Transitions
- 2.5.3 新しい開発法: エクストリームプログラミング
- 2.6 苦い眺めのまとめ
- 2.7 この章のアンチパターン
- 2.1 アンチパターンを生み育てる肥沃な土壌
- 第1章 苦い失敗談
- 第2部 サーバーサイドのJava アンチパターン
- 第3章 苦いサーブレット
- 3.1 間違った足で着地する
- 3.1.1 初期のアンチパターン: Magic Pushbutton
- 3.1.2 Model-View-Controller の使用
- 3.1.3 モデルとビューを分けない過ち
- 3.1.4 モデルの分離
- 3.2 アンチパターン: Magic Servlet
- 3.2.1 サーブレットをモデルとして使えるか
- 3.2.2 Magic Servletの罠
- 3.2.3 Magic Servlet の原因
- 3.3 解決策: Command を使ったリファクタリング
- 3.3.1 モデルの分離
- 3.3.2 コマンドオブジェクトを使ってモデルをラップする
- 3.3.3 モデルロジックの分離
- 3.3.4 リターントリップを分離する
- 3.3.5 リターントリップにJSPを使う
- 3.4 まとめ
- 3.5 この章のアンチパターン
- 3.1 間違った足で着地する
- 第4章 苦い JSP
- 4.1 家までなお道半ば
- 4.1.1 危険な兆候を察知する
- 4.2 アンチパターン: Monolithic JSPs
- 4.2.1 モデルとビューの分離がないプログラム
- 4.2.2 解決策: リファクタリングしてModel-View-Controller にする
- 4.3 アンチパターン: Compound JSPs
- 4.3.1 複数の JSP を結合すべきか
- 4.3.2 2つのインタフェースを結合するサンプル
- 4.3.3 解決策 JSPを分割する
- 4.3.4 コントローラサーブレットで条件判断を扱う
- 4.4 ミニアンチパターン: Coarse Commands と Fine Commands
- 4.4.1 グループに含まれるコマンドが多すぎる
- 4.4.2 解決策: リファクタリングして適切な粒度にする
- 4.4.3 粒度に関するヒント
- 4.5 ミニアンチパターン: Fat Commands.
- 4.6 JSPアンチパターンの復習
- 4.7 この章のアンチパターン
- 4.1 家までなお道半ば
- 第5章 苦いキャッシュ管理
- 5.1 キャッシュをよこせ!
- 5.2 アンチパターン: Cacheless Cow
- 5.2.1 キャッシュのない苦いBBS
- 5.2.2 ShowBoardのモデル、 ビュー、コントローラを作る
- 5.2.3 ShowThreadのモデル、 ビュー、コントローラを作る
- 5.2.4 AddPostのモデル、 ビュー、コントローラ
- 5.2.5 パフォーマンスの問題
- 5.3 解決策: キャッシュ
- 5.3.1 解決策1:ハードウェアキャッシュの使用
- 5.3.2 解決策2:キャッシュ対応コマンド
- 5.3.3 BBSにキャッシュを追加する
- 5.3.4 キャッシュ対応コマンドの改良案
- 5.4 キャッシュ関連ミニアンチパターン
- 5.4.1 静的キャッシュへの並行アクセス
- 5.4.2 果てしなく成長するキャッシュ
- 5.5 アンチパターン: Synchronized Read/Write Bottlenecks
- 5.5.1 読み取りの競合によるパフォーマンスの低下
- 5.5.2 読み取り/書き込みロックによる共有アクセス
- 5.6 Cacheless Cow を調理する
- 5.7 この章のアンチパターン
- 第6章 苦いメモリー
- 6.1 メモリーリークとアンチパターンについて
- 6.1.1 メモリーの管理
- 6.1.2 ガーベジコレクションについて
- 6.1.3 参照カウント
- 6.1.4 到達可能オブジェクト
- 6.2 C++からJavaに移る
- 6.2.1 Java メモリーリークの原因となる環境
- 6.2.2 Java メモリーリークの検出
- 6.3 アンチパターン: Lapsed Listeners Leak
- 6.3.1 危険なプログラミングの例
- 6.3.2 解決策1: リスナーを明示的に削除する
- 6.3.3 解決策2: アンカーのライフサイクルを短くする
- 6.3.4 解決策3: 参照を弱くする
- 6.3.5 参照オブジェクトによるメモリー管理の簡素化
- 6.4 アンチパターン: Leak Collection
- 6.4.1 キャッシュとセッションステートの問題の原因
- 6.4.2 解決策1: 兆候を探す
- 6.4.3 解決策2: add と remove をペアにする
- 6.4.4 解決策3: キャッシュでソフト参照を使う
- 6.4.5 解決策4: コレクションで弱参照を使う
- 6.4.6 解決策5: finally を使う
- 6.5 メモリリークのトラブルシュート
- 6.5.1 メモリーリークの存在を確認する
- 6.5.2 修正すべきか判断する
- 6.5.3 問題を特定する.
- 6.5.4 問題の発生源を突き止めて修正する
- 6.5.5 問題の再発を防止する
- 6.6 ミニアンチパターン: Little Hogs
- 6.6.1 文字列操作
- 6.6.2 コレクション
- 6.6.3 継承チェーン
- 6.7 まとめ
- 6.8 この章のアンチパターン
- 6.1 メモリーリークとアンチパターンについて
- 第7章 苦い接続と結合
- 7.1 接続を作る
- 7.2 アンチパターン: Connection Thrashing
- 7.2.1 アクセスのたびに作っては終了する
- 7.2.2 解決策: 接続プールによる接続の再利用
- 7.2.3 BBS をリファクタリングして接続プールを追加する
- 7.2.4 getPooledConnection の使用
- 7.2.5 J2EE コネクタアーキテクチャの使用
- 7.3 アンチパターン Split Cleaners
- 7.3.1 Split Cleaner の原因となる例外
- 7.3.2 解決策: finally で接続と後処理をペアにする
- 7.4 アンチパターン Hardwired Connections
- 7.4.1 通信バッファ
- 7.4.2 早すぎるバインド
- 7.4.3 解決策1: XMLメッセージを使った疎結合の実現
- 7.4.4 解決策2: Webサービスを使った遅延バインド
- 7.5 XML 誤用によるミニアンチパターン
- 7.5.1 XML Golden Hammer
- 7.5.2 XML の苦い変換
- 7.6 ミニアンチパターン Rigid XML
- 7.6.1 名前の衝突
- 7.6.2 厳密な構成
- 7.6.3 可変コンテンツコンテナにおける制限
- 7.6.4 XML のバージョン管理
- 7.7 まとめ: 苦い接続を甘くする
- 7.8 この章のアンチパターン
- 第8章 苦い Bean
- 8.1 Enterprise JavaBeans とは
- 8.1.1 コンポーネントベースの分散アーキテクチャ
- 8.1.2 EJB の種類
- 8.2 EJB を使った苦いBBS
- 8.2.1 EJB アプリケーションの構成要素
- 8.2.2 リモートインタフェースの作成
- 8.2.3 ホームインタフェースの作成
- 8.2.4 Bean クラスの実装
- 8.2.5 主キーの定義
- 8.2.6 配備記述子の作成
- 8.2.7 モデルの使用
- 8.3 アンチパターン: Round-tripping
- 8.3.1 分散配備のコストを計算する
- 8.3.2 饒舌なインタフェース
- 8.3.3 解決策: ファサードを使った通信往復のグループ化
- 8.3.4 Round-trippingのルーツ
- 8.3.5 ファサードを使ったBBSのリファクタリング
- 8.4 アンチパターン: Square Bean in a Round Hole. 8.4.1 ミニアンチパターン: Bean-Managed Joins
- 8.4.2 解決策:ビュー、マッパー、 Bean管理による結合
- 8.4.3 ミニアンチパターン: Entity Beans for Lightweight Functions
- 8.4.4 ミニアンチパターン: Entities for Read Only
- 8.4.5 ミニアンチパターン: Entity Beans for Write but Not Read
- 8.4.6 スクロール可能リストの問題
- 8.4.7 総合的な解決策: 作業に適したBean を選ぶ
- 8.5 ミニアンチパターン: Everything Is an EJB
- 8.6 EJB とキャッシュ
- 8.6.1 ファサードを使ったキャッシュの実装
- 8.7 苦い Beanの渋みをとる
- 8.8 この章のアンチパターン
- 8.1 Enterprise JavaBeans とは
- 第3章 苦いサーブレット
- 第3部 俯瞰図
- 第9章 苦いコーディング習慣
- 9.1 コーディングの習慣を学ぶ理由
- 9.1.1 正しい習慣付けを要求するエクストリームプログラミング
- 9.1.2 アンチパターンに対抗するコーディング基準
- 9.2 ミニアンチパターン: 読みにくいコード
- 9.2.1 名前について
- 9.2.2 命名の基準
- 9.2.3 中括弧とインデント
- 9.2.4 コメント
- 9.2.5 タブとスペース
- 9.2.6 エディタ
- 9.3 ミニアンチパターン編成と可視性
- 9.4 ミニアンチパターン: 構造
- 9.4.1 オブジェクト指向の基本原則
- 9.4.2 低レベルのデザインについて
- 9.4.3 例外
- 9.5 ミニアンチパターン: リークとパフォーマンス
- 9.6 テストに関する規則
- 9.7 良いスタイルガイドの作成
- 9.7.1 買うか、 借りるか、 盗むか
- 9.7.2 Contextual社のスタイルガイド
- 9.8 コーディング基準のまとめ
- 9.1 コーディングの習慣を学ぶ理由
- 第10章 苦いスケーラビリティ
- 10.1 パフォーマンスに適したトポロジー.
- 10.1.1 各階層が複数の同種のシステムから成る階層構造
- 10.1.2 その他のトポロジー
- 10.2 アンチパターン: Performance Afterthoughts
- 10.2.1 パフォーマンス計画のない開発
- 10.2.2 実例
- 10.2.3 解決策: パフォーマンス計画
- 10.3 アンチパターン Round-tripping
- 10.3.1 解決策: キャッシュとファサード
- 10.4 アンチパターン: Bad Workload Management
- 10.4.1 解決策: 負荷管理
- 10.4.2 真の負荷分散
- 10.5 アンチパターン: Chaotic Session Management
- 10.5.1 解決策1: セッション親和性を持つディスパッチ
- 10.5.2 解決策2: 分散状態管理サービスの利用
- 10.5.3 カスタムセッションBean を使う解決策
- 10.5.4 カスタムエンティティ Bean を使う解決策
- 10.6 アンチパターン: Thrash-tuning
- 10.6.1 解決策: 正しい方法でパフォーマンスを改善する
- 10.7 怪物パフォーマンスを飼い慣らす
- 10.8 この章のアンチパターン
- 10.1 パフォーマンスに適したトポロジー.
- 第11章 甘い未来へ
- 11.1 さまざまなレベルで役に立つアンチパターン
- 11.1.1 アンチパターンが経験を活かす
- 11.1.2 アンチパターンを活用してプログラムを改善する
- 11.1.3 アンチパターンが優れたプログラマーを育てる
- 11.2 アンチパターンをプロセスに反映する
- 11.3 現在、そして未来へ
- 11.1 さまざまなレベルで役に立つアンチパターン
- 第9章 苦いコーディング習慣
- 付録A アンチパターンのクロスリファレンス
- 参考資料
- テーマごとの参考資料
- デザインパターンとリファクタリング
- パフォーマンス
- TCP/IP
- UML
- XML
- 索引
第1章 苦い失敗談
- N/A
第2章 苦い眺め
アンチパターン: Too Many Page Items
- 多数のファイルをロードするWEBページは負荷が掛かる
アンチパターン: Excessive Layering
- オブジェクト指向システムはレイヤーを追加して複雑性を隠蔽する
- レイヤーが増えれば増えるほどパフォーマンスは悪化する
- レイヤーは極力単純に保ち、過剰なレイヤーを導入しない
ウォーターフォール開発法に伴う主要な問題
- 後戻りしない(できない)設定なのでリファクタリングの機会を奪う
- リスクの高い要素(システム統合や統合テスト)が開発サイクルの後の方に押し込められ、スケジュールが炎上する
- 要求文書の書き換えが正確に行われたか保証することが事実上不可能
アンチパターン: Incomplete Process Transitions
- 反復型開発への移行の失敗
- (1) 反復の定義
- (2) 終了条件の定義が曖昧
- (3) アーティファクト過多
- (4) チームのまとまりが悪い、あるいは教育不足
第3章 苦いサーブレット
アンチパターン: Magic Push Button
- ひとつのボタンクリックイベントのハンドラメソッドに全てのロジックが記述されている
- VBでよく見られたアンチパターン
- [MEMO]
- 実際よく見た
アンチパターン: Magic Servlet
-
Magic Push Button
と同じでひとつのリクエストをサーブレットのメソッドに全てのロジックが記述されている - サーブレットが流行り始めた初期の頃はよく見られたアンチパターン
- [MEMO]
- PHPでもよく見た
Magic Servletの問題点
- (1) 担当が分離できない
- フロントエンドとバックエンドの担当を分離できない
- (2) 保守性低下
- フロントエンドとバックエンドが混在しているので保守が異様に困難
- (3) 信頼性が低下
- ひとつのメソッドに全てのロジックが詰め込まれているので、ひとつの修正が別の不具合を産む可能性が高い
- (4) 再利用性が低下
- ひとつのメソッドに全てのロジックが詰め込まれているので、再利用がほぼ不可能
Magic Servletの原因
- (1) 経験不足
- ソフトウェア設計の知識・経験が不足している
- (2) Perlの書き直し
- Perlプログラムを直接移植
- (3) 移植一般
- 参考にしたプログラムがそもそも品質が低かった
- (4) ツールの力不足
- 自動生成ツールが生成したコードがそもそも品質が低かった
Commandを使ったリファクタリング
- ビジネスロジックをCommand(パターン)に分離し、サーブレットからCommandを呼ぶというリファクタリング
- リファクタリングの第1歩として有効
第4章 苦いJSP
タグ言語
- HTMLタグの中にスクリプトを埋め込めるタイプのプログラミング言語、ツール
- JSPやASP、PHPなどのこと
タグ言語を使った場合の問題点
- (1) ビジネスロジックとビューが密結合になる
- (2) ビジネスロジックがタグ言語・スクリプトなどで処理される(パフォーマンスや保守性が低下する)
- (3) フロントエンドとバックエンドの役割が分離されない
- (4) 通信手段が限定される
- (5) タグが独自化する
アンチパターン: Monolithic JSPs
- JSPの中に全てのロジックを記述している
-
Magic Servlet
のJSP版 - MVCアーキテクチャにリファクタリングするべし
- [MEMO]
- 初期のPHPでもよく見られたアンチパターン
アンチパターン: Compound JSPs
- JSPの中に巨大なIF文があり、フラグによって表示内容を切り替えている(出力するHTMLを制御している)
- 本来復数のJSPに分割すべき処理をひとつのJSPで賄おうとしている状況
- 悪い意味での怠惰なプログラム
- 素直にJSPを分割せよ
- [MEMO]
- PHPでもよく見た
- というか、プログラマブルなテンプレートエンジンでは必ずやらかす奴が出てくるパターン
アンチパターン: Coarse Commands と Fine Commands
- コマンドの粒度が大き過ぎる、または小さすぎる
- WEBアプリケーションが扱う処理の粒度として適切な粒度を見極める必要がある
- [MEMO]
- 現在だとREST原則なんかのお陰でURL設計時点である程度リソースの大きさと処理の規模感を考えることができるので、あまり遭遇しない状況かも
アンチパターン: Fat Commands
- 大き過ぎるコマンド
- 取り扱う責務が大き過ぎる
-
Magic Servlet
がコマンドにスライドしてきただけと言える
第5章 苦いキャッシュ管理
- N/A
第6章 苦いメモリー
- Java固有の問題なので読み飛ばし
第7章 苦い接続と結合
アンチパターン: Connection Thrashing
- リクエストの度に新しいDB接続オブジェクトを生成している
- DB接続生成のコストは大きいので、毎回DB接続を生成しているとシステムのパフォーマンスが低下する
- コネクションプーリングを導入するべき
アンチパターン: Split Cleaners
- リソースの取得と解放が別の場所になっている
- 開放し忘れが発生する可能性が非常に高い
- リソースの取得と解放は極力近い場所で行うべき
アンチパターン: Hardwired Connections
- 必要以上に密結合な外部API
- [MEMO]
- いまいち想像がつかない
アンチパターン: XML Misue
- XMLをDBとして使おうとしている
- XMLのロード・解析はコストの高い処理なのでパフォーマンスが出ない
- 素直にRDBを使おう
- [MEMO]
- XML DBなんてものもあったけど、全然流行らず消えた
- ドキュメントDBも一瞬盛り上がったけど、主流にはならなかった
アンチパターン: Rigid XML
- XMLの拡張を制限する
- [MEMO]
- 今となってはXML自体あまり使われないので、考慮することもなさそう
第8章 苦いBean
- EJBを使う時の問題
- 読み飛ばした
第9章 苦いコーディング習慣
- [WIP]
第10章 苦いスケーラビリティ
- [WIP]
第11章 甘い未来へ
- [WIP]