色々なパターンについて

約5分で読めます

はじめに

今回はデザインパターン・アンチパターンについて話したいと思います。 まず、今回の趣旨を伝えておきます。 今回は「デザインパターン・アンチパターン」というものを「認知」していただければ成功かと思います。 この後、いくつか実際のパターンなども紹介しますが、すべて覚える必要はないです。また忠実に守る必要もないです。  

実際に問題に直面したときや、設計前などに、存在することを知っていれば、その時に詳しく調べればいいのです。 その助けになれば良いかなと思います。

1. プログラミングにおけるデザインパターン

デザインパターンとは、ソフトウェア設計において繰り返し現れる問題に対する、先人たちが積み上げた「再利用可能な解決策の型(テンプレート)」 のことです。1994年に出版されたエリック・ガンマらによる書籍(通称:GoF)によって広く普及しました。 デザインパターンを採用する目的は、単に「コードを綺麗にする」ことだけではありません。以下の3つの質を向上させることにあります。

  • 保守性: 修正が必要な際、影響範囲を最小限に抑えられる。
  • 拡張性: 新しい機能を追加する際、既存のコードを壊さずに済む。
  • 共通言語: 開発者同士が「ここはObserverで」と言うだけで、複雑な設計意図を瞬時に共有できる。

有名なパターン(抜粋)

パターン名概要主な使いどころメリット
Singletonインスタンスを1つに制限DB接続、ログ出力、設定管理リソース重複防止、状態の一元管理
Factory Method生成ロジックをクラスに委譲OS毎のUI生成、プラグイン呼び出し側が具体名を知らずに済む
Observer状態変化の自動通知イベント通知、SNS、MVC疎結合なリアルタイム連携が可能
Strategyアルゴリズムの動的切替決済手段切替、ソート選択if/switch文を排除し拡張性向上
Adapterインターフェースの変換レガシーコードの再利用既存コードを壊さず新環境に適合

2. プログラミングにおけるアンチパターン

アンチパターンとは、一見すると効率的または合理的な解決策に見えますが、実際には長期的には悪影響(保守性の低下、バグの増加、パフォーマンス劣化など)を及ぼすことが証明されている、避けるべき設計・実装の型のことです。 デザインパターンが「ベストプラクティス(最善策)」の集積であるのに対し、アンチパターンは 「ワーストプラクティス(失敗の典型例)」 を体系化したものです。 アンチパターンは、悪意を持って作られるものではありません。多くの場合、以下のような「一見正当な理由」から発生します。

  • 知識不足: 適切なデザインパターンや言語のベストプラクティスを知らない。
  • 短期的な効率: 「今は動けばいい」「納期が最優先」というプレッシャー。
  • 文脈の誤解: ある場面では正解だった手法を、不適切な場面に無理やり適用する。
  • 過剰な一般化: 将来使うかもしれないという憶測で、過度に複雑な抽象化を行う。

有名なパターン(抜粋)

パターン名特徴弊害対策
Spaghetti Code複雑に絡み合った制御構造解読不能、修正の影響範囲不明関数分割、単一責任の原則を適用
God Object一つのクラスに機能が集中保守性低下、修正時の連鎖バグ責任に応じたクラスの適切な分割
Golden Hammer特定の技術を無理に適用効率低下、不適切なアーキテクチャ適材適所の技術選定と多角的な視点
Cargo Cult理解せずコピペで実装不要なコード、予期せぬ挙動コードの意味を理解し、不要を削る
Magic Numbers生の数値が直接記述される意図が不明、変更漏れの発生定数(const/enum)に名前を付ける

3. データベース設計のアンチパターン

データベース設計におけるアンチパターンとは、RDB(リレーショナルデータベース)の数学的基礎である「リレーショナルモデル」や「正規化理論」を軽視した結果、データの整合性、クエリのパフォーマンス、およびアプリケーションの拡張性を損なう設計のことを指します。 DBの構造は一度運用が始まると変更が非常に困難(破壊的変更になりやすい)なため、設計段階でこれらの罠を回避することが極めて重要です。

DB設計においてアンチパターンが紛れ込む背景には、特有の力学が働いています。

  • アプリケーション視点への偏り: データベースを単なる「データの永続化先(ストレージ)」と捉え、オブジェクト指向のデータ構造をそのままテーブルに投影しようとする。
  • 不適切な柔軟性の追求: 「将来どんなデータが来るかわからない」という不安から、テーブル構造を汎用化しすぎる(例:EAV)。
  • SQLへの不慣れ: 複雑なJOINを避けようとして、一つのカラムにデータを詰め込んだり、非正規化を過剰に行ったりする。

有名なパターン(抜粋)

パターン名特徴弊害対策
Jaywalkingカンマ区切りの文字列保存検索低速、集計が困難交差テーブルへの正規化
Naive Treesparent_idのみの階層管理複雑な再帰クエリ、削除の困難さ閉包テーブル等の階層モデル採用
EAV (汎用属性)属性と値を別々の行で保持型の不備、結合過多による鈍化正当な正規化、またはJSONB活用
Multi-Columntag1, tag2とカラムを増設保存数の制限、検索処理の複雑化従属テーブルへの切り出し
Polymorphic1つの外部キーが複数表を指す外部キー制約が使えず整合性破壊親ごとの交差テーブル作成
TOP