世界最強の

ソフトウェアアーキテクト
小川 雄大
1
小川 雄大

(おがわ かつひろ)
ソーシャルマーケティング開発部
著書

パーフェクトPHP

効率的なWebアプリケーションの作り方
2
アシアル (2008) - クロコス(2011) - ヤフー(2014)
– ソフトウェアアーキテクチャ - Wikipedia
“ソフトウェアアーキテクチャ(Software
Architecture)は、ソフトウェアコンポーネント、
それらの外部特性、またそれらの相互関係から構
成される。”
3
– IEEE 1471 - Wikipedia
“アーキテクト(仕組士):
システムのアーキテクチャを設計する責任がある、
人、チーム、あるいは組織”
4
対象者
• コードの質を高めたいと思っている人
• 設計に興味を持っている人
• 設計がうまくいかず悩んでいる人
• 効率的にコードを書きたいと思っている人
• 開発現場に秩序をもたらしたい人
5
ゴール
• 自分やチームメンバーが書いたコードを

よりよくしたい気持ちになる
• 設計における考え方の指針を得る
6
アジェンダ
1. 技術的負債
2. メンタルモデルとオブジェクト指向設計
3. 設計原則とパターン
4. アーキテクトのメンタル
7
技術的負債
8
– ニール・フォード
(ソフトウェアアーキテクトが知るべき97のこと)
“本質的な複雑さは単純に、
付随的な複雑さは取り除け”
9
技術的負債の例
10
重複だらけのコード
• 修正したと思ったら修正漏れがあった…
11
理解しづらいコード
• 変更したい箇所で何やってるかわからなくて
どう変えていいかわからない…

• どこを変えればいいかすらわからない…

• 機能追加したら思わぬバグがでた…
12
拡張性のないコード
• 修正したいけどあれもこれも直さなきゃ…

• 1箇所変更したいだけなのにここをいじると

影響範囲が広すぎて直したくない…
13
古くなったライブラリ
• サポート期限きれた…

• 使いたい機能が使えない…

• 放置しすぎてもはやバージョンアップ

できない…
14
もうヤダこのシステム...
15
こんなことを繰り返していると
となってしまいます
技術的負債を駆逐する
• コードを書く以上は発生し続ける負債

• 負債を完全になくすのは不可能

• コードを破棄するほかない
16
技術的負債を駆逐する
• 新たにコードが発生する際に負債に

なりにくいよう設計する

• 時が経ち古くなったコードを継続的に

改修していく

• 設計の知識、テクニック、経験が要求される
17
組織として取り組んでいく
• 企業・チームで開発をする以上、

個人だけの問題ではない

• 規約やガイドラインを制定して

ルール・知見を共有し秩序をもたらす

• コードレビューを実施して品質向上と共に

チーム全体の技術向上を図る
18
技術的負債ではなく

技術的資産を
19
技術的資産
• ライブラリ・フレームワーク化

• 統一・洗練された思想やインターフェイス

• 整理されたドキュメント

• それらをオープンソース化して

業界のイニシアチブをとる
20
メンタルモデルと

オブジェクト指向設計
21
– メンタルモデル - Wikipedia
“メンタルモデル(英: mental model)とは、

人間が実世界で何かがどのように作用するかを
思考する際のプロセスを表現したものである。”
22
メンタルモデル
• 思考のプロセスを表現したもの
• 利用者がどのように考えてシステムを

利用するか

• プロダクトオーナーがどのような仕様に

したいと考えているか

• 開発者の抱く実装イメージ
23
メンタルモデルをコードで表現する
• ショッピングカートの例

A. $_SESSION[‘cart’][$item->getId()]+=$num;
B. $cart->addItem($item, $num);
• 剥き出しの実装にインターフェイスを被せる

• オブジェクト指向プログラミングの本質
• 具体的な実装はカプセル化
24
ユースケースとインターフェイス
• ユースケースを洗い出し、

それを扱うインターフェイスを定義する

• ここでいうインターフェイスは言語機能の

ことではなく、より広義の意味
25
ショッピングカートのユースケース
• ユースケース

• カートに商品を追加できる

• カートに商品を追加する際に個数を指定できる

• インターフェイス

• class Cart
• public function addItem(Item $item, $num)
26
Facebook PHP SDK
• $fb = new Facebook([

'app_id' => '{app-id}',

'app_secret' => '{app-secret}',

]);
• $response = $fb->get('/me', '{token}');
• $me = $response->getGraphUser();
• echo $me->getName();
27
– Trygve Reenskaug
(The DCI Architecture:

A New Vision of Object-Oriented Programming)
“MVC is about
people and their mental models
—not the Observer pattern”
28
チームにおける認識の共有
• 仕様についてチーム内で話し合うときに、

固有名詞やその意味を共通化する

• ユーザー?アカウント?利用者?

• ユビキタス言語
• “共有されたチームの言語”
29
– エリック・エヴァンスのドメイン駆動設計
第2章 コミュニケーションと言語の使い方
“チーム内のすべてのコミュニケーションとコード
において、その言語を厳密に用いることを、チー
ムに約束させること。図やドキュメント、そして
何より会話の中では同一の言語を使用すること。”
30
本質的な複雑さは単純に
• メンタルモデルに沿って設計を進めることで

インターフェイスが洗練される

• コードが理解しやすくなり、修正や拡張も

行いやすくなる

• シンプルに、文章のようなコーディングを
31
難しいところ
• 実現するためにはオブジェクト指向設計の

ノウハウや経験が求められる

• メンタルモデルを的確に捉え、コード上に

表現しつつ、複雑な実装の裏側はカプセル化
する、ということは簡単なことではない

• シンプルがゆえに「これが普通」だと捉えら
れるかも
32
設計原則とパターン
33
設計の原則/パターン
• 原則やパターンは開発における基礎知識

• 原則は負債を生み出しにくくするために

• パターンは負債を取り除くために
34
パターンの乱用による弊害
• ただし乱用すると却って複雑に

• “本質的な複雑さは単純に、

付随的な複雑さは取り除け”

• 常に本質的な問題の解決を意識し優先する
35
パターン
36
パターンとは
• 設計ノウハウに名称をつけて共有されたもの

• 「こういった問題に対してはこのパターンを
適応することで解決できる」

• たくさんあるので詳細は省略
37
GoF
• デザインパターン集

• State/Strategyパターンはオブジェクト指向

における基本的なテクニック
38
DDD
• ドメイン駆動設計 (Domain Driven Design)

• 本質的な問題解決をするためのパターン集
39
エリック・エヴァンスのドメイン駆動設計
• DDD
40
PofEAA
• エンタープライズアプリケーション

アーキテクチャパターン

(Patterns of Enterprise Application Architecture)

• アーキテクチャパターン集
41
エンタープライズアプリケーション

アーキテクチャパターン
• PofEAA
42
リファクタリング
• リファクタリングを

行う手順に関する

パターン集
43
リーダブルコード
• 読みやすいコードを

書くためパターン集
44
DCI
• Data Context Interaction

• データ、コンテキスト、相互作用

• MVCのようにメンタルモデルを表現する手法

• MVCの考案者らによる提案
45
さまざまな役割
• Controller

• Entity

• Repository

• Service

• Usecase

• Api
46
原則
47
原則
• こういうことしたら問題になりやすいから

やっちゃだめだよという知見
48
DRY
• Don’t Repeat Yourself

• 重複してはならない
49
SOLID
• オブジェクト指向設計の5つ原則の頭文字

• 単一責任の原則

(SRP : Single Responsibility Principle)

• オープン・クローズドの原則

(OCP : Open Closed Principle)

• リスコフの置換原則

(LSP : Liscov Substitution Principle)

• インターフェイス分離の原則

(ISP : Interface Segregation Principle)

• 依存性逆転の原則

(DIP : Dependency Inversion Principle)
50
単一責任の原則 (SRP)
• "クラスを変更する理由は1つでなければ

ならない"

• クラスの責任は1つにして複雑化などを防ぐ
51
オープン・クローズドの原則 (OCP)
• "拡張に対して開いていて、修正に対して

閉じていなければならない"

• 既存のコードに手を入れることなく

修正・拡張できるようにする
52
リスコフの置換原則 (LIP)
• "派生型は基本型と置き換え可能でなければ

ならない"

• 継承によって親クラスの実装を全く別のもの
に変えてしまうのは間違った継承である
53
インターフェイス分離の原則 (ISP)
• "クライアントに、クライアントが利用しない
メソッドへの依存を強制してはならない"

• 利用するクライアントの視点から

インターフェイスを定義しよう
54
依存関係逆転の原則 (DIP)
• "上位モジュールは下位モジュールに依存してはな
らない。どちらも「抽象」に依存するべきである"

• "「抽象」は実装の詳細に依存してはならない。

実装の詳細が「抽象」に依存すべきである。"

• 実装からインターフェイスを抜き出すのではな
く、要求に応じてインターフェイスを定義し、イ
ンターフェイスにあわせて実装する
55
アジャイルソフトウェア開発の奥義
• SOLID原則
56
効率的なWebアプリケーションの作り方
• オブジェクト指向や

設計ノウハウなどを

体系的に学べる
57
YAGNI
• You Ain't Gonna Need It!

• 実際に必要になるまで機能追加しない

• “本質的な複雑さは単純に、

付随的な複雑さは取り除け”
58
アーキテクトのメンタル
59
経験は必要不可欠
• 失敗を恐れずに、「やってはいけないこと」
を身をもって覚える

• 書いたコードを振り返り、よりよくなるには
どうしたらようかを考える

• そうして経験値として積み重ねたものが

アーキテクトの支えになる
60
コードの資産価値を高める
• 再利用可能なコードを探しては抜き出し、

ライブラリ化して共有する

• コードをオープンにして利用者を増やし、

コードの成長を促す
61
先人の知恵から学ぶ
• 本やドキュメントを読み、原則・パターン化
された知恵を身につけていく

• 先人と同じ過ちを繰り返さない

• 知識の継承
62
責任を持つ
• 修正や拡張を行う際にリスクを恐れて

メンタルモデルにそぐわないコードを書くと
技術負債として重くのしかかる

• リスクをとるか、負債をとるかは

アーキテクトとして責任をもって判断する

• 誰かが責任を持たないと全員が不幸になる
63
“本質的な複雑さは単純に、

付随的な複雑さは取り除け”
64
ご清聴ありがとうございました
65

世界最強のソフトウェアアーキテクト