SlideShare a Scribd company logo
1 of 33
凝集度と責務
トイレのレバーが遠すぎて流すことができません
今回のテキスト
keywords
DDD, オブジェクト指向
プログラムを初めて勉強したとき
「同じ処理は共通化することで、効率化を測るのがいいプログラムである」
みたいなことを勉強する
DRY(Don’t Repeat Yourself)原則(っぽい何か)
同じコードを書くな!
処理を共通化して、ロジックを1箇所に!
それで修正するときは1箇所の修正で済むのだ!
DRY原則(本物)
すべての知識はシステム内において、単一、かつ明確な、そして
信頼できる表現になっていなければならない。
(達人プログラマ 第2章 7 二重化の過ち)
完全に理解した
フルネームってつまり、間に空白がある文字列。よし、共通化だ!
※普段もうこんなコード書かないので頑張って絞り出した
共通機能ライブラリ
方式(CommonとかUtil
とか)
共通化が保守性を下げている。。?
middleNameも追加で。
えっ。。
おかしい。。共通化した箇所、修正のたびに影
響範囲は広くて修正しづらい。
てか、この関数何用の関数なんだ?
邪魔だなこの関数。
何がおかしかったのか?
「データクラス」と「機能クラス」に別れた
手続き型の設計になってしまっていた
手続的設計でおこる
ダメな共通化
共通機能ライブラリ
● 汎用的な共通関数
● 用途ごとに細分化した共
通関数
汎用的な共通関数
手続的設計でおこるダメな共通化1
用途ごとに細分化し
た共通関数
手続的設計で起こるダメな共通化2
クラスはデータとロジ
ックを一緒に扱うため
の機能
オブジェクト指向をやろう
本来あって欲しかった姿
手続的設計からオブジェクト指向へ
● データをロジックを分ける実装では距離が離れすぎてどこで何をしているかの見通しがつかな
くなる。
● 機能・操作に着目すると手続的になりがち。
● DRY原則は処理をまとめる共通化のことではない。知識をシステム内で単一にしろという話。
● オブジェクトに注目することでDRY原則を満たせるようになる。
いい設計をするため
に必要な2つの視点
● 凝集度
● 責務
オブジェクト指向らしく設計する
ために
凝集度
関連性の高いデータとロジックだけを集めたクラスを凝集度が高いと言う。
責務
責務は、ソフトウェアオブジェクトについて大ざっぱに記述したものです。責務には、以下の3つの
主要な項目が含まれます。
● オブジェクトが行う動作
● オブジェクトが持つ知識
● オブジェクトが他に影響を与える主要な判断
(オブジェクトデザイン 4.1 責務とは何か)
「トイレ」クラスの例
低凝集な実装とは、トイレで用を足して、流そうとしたら流すための
レバーが100m先の他人の家のキッチンにあるような状態のこと。
責務が不明瞭とは、炊飯機能付きトイレのようなもの。
トイレの仕様
● タンク(便器で水を貼っているところ)を持つ
● 流すことができる
低凝集なトイレ
責務がおかしいトイレ
高凝集かつ責務が正しいトイレ
オブジェクト指向らしい設計にするには
● メソッドをロジックの置き場所にする
● ロジックを、データを持つクラスに移動する
● 使う側のクラスにロジックを書き始めたら、設計を見直す
● メソッドを短くして、ロジックの移動をやりやすくする
● メソッドでは必ずインスタンス変数を使う
● クラスが肥大化したら小さく分ける
● パッケージを使ってクラスを整理する
現場で役立つシステム設計の原則 〜変更を楽で安全にするオブジェクト指向の実践技法 増田 亨
危険な臭い
やりがちで、低凝集、責務不明瞭を引き
起こす具体例
● 定数クラス
● Common, Utilクラス
低凝集、責務不明瞭の兆候
低凝集の代表、定数クラス
固定値のパターンを表現するのに使われる。
定数をまとめて管理しているので、修正が発生しても修正が容易なように見える。
しかし、その定数がどこでどのように振る舞い、なんのための値なのかが結局のところ変数名くらい
しか手がかりがない。
ロジックと値の距離が遠くなりがち
よくあるのはやはり右のような例。
DNAの定義として、Adenine, Thymine, Cytosine,
Guanineがありますって言われた時にその対応を
Constantsオブジェクトに書いて、判定でConstantsと
比較してしまう。
DNAの使用表現として浅いし、これ以上何もできない。
Constantsクラスはファットになりがち。
またロジックも各所に出てきちゃうので、DRY的にも
NG
sealed trait, sealed abstract class を使って、
固定パターンは表現します。
コードなどの対応がある場合は、ファクト
リを準備して生成できるようにしておくと
良いです。
ファクトリはテストが必要です。
これならば、DNAにはどのようなパター
ンがあって、それぞれどういう特徴、仕様
を持つのかさらに追加で記述することも可
能です。
どうすべきか?
責務不明瞭の代表、Common, Util クラス
この手のクラスが存在する時、どのオブジェクトの振る舞いとして表現すべきかが考えきれていない。
データとそれに対する処理が遠いので、どのクラスで使うのか?なんの値の仕様なのかがわかりにく
く、見通しがつかなくなる。
そもそも気づくことも難しいので、似たような処理が複数箇所で作られかねない。
まとめ
● 手続的な設計ではなく、オブジェクト指向に
● データクラスと機能クラスに分けてはいけない
● いい設計のポイントは凝集度と責務を常に考えること
● 定数クラスやUtilを使わない。おくべき場所が他にあるはず。

More Related Content

What's hot

Unityでオニオンアーキテクチャ
UnityでオニオンアーキテクチャUnityでオニオンアーキテクチャ
Unityでオニオンアーキテクチャtorisoup
 
ドメインオブジェクトの見つけ方・作り方・育て方
ドメインオブジェクトの見つけ方・作り方・育て方ドメインオブジェクトの見つけ方・作り方・育て方
ドメインオブジェクトの見つけ方・作り方・育て方増田 亨
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪Takuto Wada
 
ドメイン駆動設計に15年取り組んでわかったこと
ドメイン駆動設計に15年取り組んでわかったことドメイン駆動設計に15年取り組んでわかったこと
ドメイン駆動設計に15年取り組んでわかったこと増田 亨
 
オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?Moriharu Ohzu
 
Windowsフォームで大丈夫か?一番良いのを頼む。
Windowsフォームで大丈夫か?一番良いのを頼む。Windowsフォームで大丈夫か?一番良いのを頼む。
Windowsフォームで大丈夫か?一番良いのを頼む。Yuya Yamaki
 
ドメイン駆動設計サンプルコードの徹底解説
ドメイン駆動設計サンプルコードの徹底解説ドメイン駆動設計サンプルコードの徹底解説
ドメイン駆動設計サンプルコードの徹底解説増田 亨
 
ソフトウェアにおける 複雑さとは何なのか?
ソフトウェアにおける 複雑さとは何なのか?ソフトウェアにおける 複雑さとは何なのか?
ソフトウェアにおける 複雑さとは何なのか?Yoshitaka Kawashima
 
ソフトウェア設計の学び方を考える
ソフトウェア設計の学び方を考えるソフトウェア設計の学び方を考える
ソフトウェア設計の学び方を考える増田 亨
 
ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計Yoshinori Matsunobu
 
ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方増田 亨
 
DDDはオブジェクト指向を利用してどのようにメンテナブルなコードを書くか
DDDはオブジェクト指向を利用してどのようにメンテナブルなコードを書くかDDDはオブジェクト指向を利用してどのようにメンテナブルなコードを書くか
DDDはオブジェクト指向を利用してどのようにメンテナブルなコードを書くかKoichiro Matsuoka
 
ソフトウェア開発のやり方の改善
ソフトウェア開発のやり方の改善ソフトウェア開発のやり方の改善
ソフトウェア開発のやり方の改善増田 亨
 
やはりお前らのMVCは間違っている
やはりお前らのMVCは間違っているやはりお前らのMVCは間違っている
やはりお前らのMVCは間違っているKoichi Tanaka
 
ドメインオブジェクトの設計ガイドライン
ドメインオブジェクトの設計ガイドラインドメインオブジェクトの設計ガイドライン
ドメインオブジェクトの設計ガイドライン増田 亨
 
世界でいちばんわかりやすいドメイン駆動設計
世界でいちばんわかりやすいドメイン駆動設計世界でいちばんわかりやすいドメイン駆動設計
世界でいちばんわかりやすいドメイン駆動設計増田 亨
 
ドメイン駆動で開発する ラフスケッチから実装まで
ドメイン駆動で開発する ラフスケッチから実装までドメイン駆動で開発する ラフスケッチから実装まで
ドメイン駆動で開発する ラフスケッチから実装まで増田 亨
 
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話Koichiro Matsuoka
 
ZDD基礎
ZDD基礎ZDD基礎
ZDD基礎reew2n
 

What's hot (20)

Unityでオニオンアーキテクチャ
UnityでオニオンアーキテクチャUnityでオニオンアーキテクチャ
Unityでオニオンアーキテクチャ
 
ドメインオブジェクトの見つけ方・作り方・育て方
ドメインオブジェクトの見つけ方・作り方・育て方ドメインオブジェクトの見つけ方・作り方・育て方
ドメインオブジェクトの見つけ方・作り方・育て方
 
例外設計における大罪
例外設計における大罪例外設計における大罪
例外設計における大罪
 
C++の黒魔術
C++の黒魔術C++の黒魔術
C++の黒魔術
 
ドメイン駆動設計に15年取り組んでわかったこと
ドメイン駆動設計に15年取り組んでわかったことドメイン駆動設計に15年取り組んでわかったこと
ドメイン駆動設計に15年取り組んでわかったこと
 
オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?
 
Windowsフォームで大丈夫か?一番良いのを頼む。
Windowsフォームで大丈夫か?一番良いのを頼む。Windowsフォームで大丈夫か?一番良いのを頼む。
Windowsフォームで大丈夫か?一番良いのを頼む。
 
ドメイン駆動設計サンプルコードの徹底解説
ドメイン駆動設計サンプルコードの徹底解説ドメイン駆動設計サンプルコードの徹底解説
ドメイン駆動設計サンプルコードの徹底解説
 
ソフトウェアにおける 複雑さとは何なのか?
ソフトウェアにおける 複雑さとは何なのか?ソフトウェアにおける 複雑さとは何なのか?
ソフトウェアにおける 複雑さとは何なのか?
 
ソフトウェア設計の学び方を考える
ソフトウェア設計の学び方を考えるソフトウェア設計の学び方を考える
ソフトウェア設計の学び方を考える
 
ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計
 
ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方ドメイン駆動設計のための Spring の上手な使い方
ドメイン駆動設計のための Spring の上手な使い方
 
DDDはオブジェクト指向を利用してどのようにメンテナブルなコードを書くか
DDDはオブジェクト指向を利用してどのようにメンテナブルなコードを書くかDDDはオブジェクト指向を利用してどのようにメンテナブルなコードを書くか
DDDはオブジェクト指向を利用してどのようにメンテナブルなコードを書くか
 
ソフトウェア開発のやり方の改善
ソフトウェア開発のやり方の改善ソフトウェア開発のやり方の改善
ソフトウェア開発のやり方の改善
 
やはりお前らのMVCは間違っている
やはりお前らのMVCは間違っているやはりお前らのMVCは間違っている
やはりお前らのMVCは間違っている
 
ドメインオブジェクトの設計ガイドライン
ドメインオブジェクトの設計ガイドラインドメインオブジェクトの設計ガイドライン
ドメインオブジェクトの設計ガイドライン
 
世界でいちばんわかりやすいドメイン駆動設計
世界でいちばんわかりやすいドメイン駆動設計世界でいちばんわかりやすいドメイン駆動設計
世界でいちばんわかりやすいドメイン駆動設計
 
ドメイン駆動で開発する ラフスケッチから実装まで
ドメイン駆動で開発する ラフスケッチから実装までドメイン駆動で開発する ラフスケッチから実装まで
ドメイン駆動で開発する ラフスケッチから実装まで
 
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話DDD x CQRS   更新系と参照系で異なるORMを併用して上手くいった話
DDD x CQRS 更新系と参照系で異なるORMを併用して上手くいった話
 
ZDD基礎
ZDD基礎ZDD基礎
ZDD基礎
 

Similar to 凝集度と責務

オブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツオブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツ増田 亨
 
PHP基礎勉強会
PHP基礎勉強会PHP基礎勉強会
PHP基礎勉強会Yuji Otani
 
Hokkaido.pm #11
Hokkaido.pm #11Hokkaido.pm #11
Hokkaido.pm #11moznion
 
プログラミング勉強会 その0
プログラミング勉強会 その0プログラミング勉強会 その0
プログラミング勉強会 その0Hirokazu Fukami
 
20100324 勉強会資料(ドメイン駆動)
20100324 勉強会資料(ドメイン駆動)20100324 勉強会資料(ドメイン駆動)
20100324 勉強会資料(ドメイン駆動)Masayuki Kanou
 
ノーコード・ローコード開発の意義
ノーコード・ローコード開発の意義ノーコード・ローコード開発の意義
ノーコード・ローコード開発の意義千紘 佐野
 
読みやすいプログラム、書き換えやすいプログラム
読みやすいプログラム、書き換えやすいプログラム読みやすいプログラム、書き換えやすいプログラム
読みやすいプログラム、書き換えやすいプログラムamusementcreators
 
可読性について リーダブルコード part1(表面上の改善)
可読性について リーダブルコード part1(表面上の改善)可読性について リーダブルコード part1(表面上の改善)
可読性について リーダブルコード part1(表面上の改善)tak
 
アプリでもオブジェクト指向エクササイズ(Potatotips#3)
アプリでもオブジェクト指向エクササイズ(Potatotips#3)アプリでもオブジェクト指向エクササイズ(Potatotips#3)
アプリでもオブジェクト指向エクササイズ(Potatotips#3)Shoichi Matsuda
 
Howtoよいデザイン
HowtoよいデザインHowtoよいデザイン
HowtoよいデザインHiroki Yagita
 
使い捨て python コードの書き方
使い捨て python コードの書き方使い捨て python コードの書き方
使い捨て python コードの書き方Sho Shimauchi
 
Node.js Tutorial at Hiroshima
Node.js Tutorial at HiroshimaNode.js Tutorial at Hiroshima
Node.js Tutorial at HiroshimaYoshihiro Iwanaga
 
Hey It's Not My TDD!
Hey It's Not My TDD!Hey It's Not My TDD!
Hey It's Not My TDD!Yasui Tsutomu
 
eZ Publish 2012年4月勉強会 - eZ Publish設計ベストプラクティス
eZ Publish 2012年4月勉強会 - eZ Publish設計ベストプラクティスeZ Publish 2012年4月勉強会 - eZ Publish設計ベストプラクティス
eZ Publish 2012年4月勉強会 - eZ Publish設計ベストプラクティスericsagnes
 
ジェネリクスの概論とか
ジェネリクスの概論とかジェネリクスの概論とか
ジェネリクスの概論とかnagise
 
オブジェクト指向っぽい話
オブジェクト指向っぽい話オブジェクト指向っぽい話
オブジェクト指向っぽい話Tomohiro Shinden
 

Similar to 凝集度と責務 (20)

凝集度と責務
凝集度と責務凝集度と責務
凝集度と責務
 
オブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツオブジェクト指向の設計と実装の学び方のコツ
オブジェクト指向の設計と実装の学び方のコツ
 
PHP基礎勉強会
PHP基礎勉強会PHP基礎勉強会
PHP基礎勉強会
 
Hokkaido.pm #11
Hokkaido.pm #11Hokkaido.pm #11
Hokkaido.pm #11
 
プログラミング勉強会 その0
プログラミング勉強会 その0プログラミング勉強会 その0
プログラミング勉強会 その0
 
20100324 勉強会資料(ドメイン駆動)
20100324 勉強会資料(ドメイン駆動)20100324 勉強会資料(ドメイン駆動)
20100324 勉強会資料(ドメイン駆動)
 
Nds#24 単体テスト
Nds#24 単体テストNds#24 単体テスト
Nds#24 単体テスト
 
ノーコード・ローコード開発の意義
ノーコード・ローコード開発の意義ノーコード・ローコード開発の意義
ノーコード・ローコード開発の意義
 
読みやすいプログラム、書き換えやすいプログラム
読みやすいプログラム、書き換えやすいプログラム読みやすいプログラム、書き換えやすいプログラム
読みやすいプログラム、書き換えやすいプログラム
 
可読性について リーダブルコード part1(表面上の改善)
可読性について リーダブルコード part1(表面上の改善)可読性について リーダブルコード part1(表面上の改善)
可読性について リーダブルコード part1(表面上の改善)
 
アプリでもオブジェクト指向エクササイズ(Potatotips#3)
アプリでもオブジェクト指向エクササイズ(Potatotips#3)アプリでもオブジェクト指向エクササイズ(Potatotips#3)
アプリでもオブジェクト指向エクササイズ(Potatotips#3)
 
Tdd
TddTdd
Tdd
 
Howtoよいデザイン
HowtoよいデザインHowtoよいデザイン
Howtoよいデザイン
 
使い捨て python コードの書き方
使い捨て python コードの書き方使い捨て python コードの書き方
使い捨て python コードの書き方
 
Node.js Tutorial at Hiroshima
Node.js Tutorial at HiroshimaNode.js Tutorial at Hiroshima
Node.js Tutorial at Hiroshima
 
Hey It's Not My TDD!
Hey It's Not My TDD!Hey It's Not My TDD!
Hey It's Not My TDD!
 
eZ Publish 2012年4月勉強会 - eZ Publish設計ベストプラクティス
eZ Publish 2012年4月勉強会 - eZ Publish設計ベストプラクティスeZ Publish 2012年4月勉強会 - eZ Publish設計ベストプラクティス
eZ Publish 2012年4月勉強会 - eZ Publish設計ベストプラクティス
 
ジェネリクスの概論とか
ジェネリクスの概論とかジェネリクスの概論とか
ジェネリクスの概論とか
 
Coderetreat
CoderetreatCoderetreat
Coderetreat
 
オブジェクト指向っぽい話
オブジェクト指向っぽい話オブジェクト指向っぽい話
オブジェクト指向っぽい話
 

凝集度と責務

Editor's Notes

  1. って思ってました。
  2. 原点はコードの二重化ではなく、知識の二重化を話している。
  3. 普段書かないから例が出てこないので絞り出しました。 いや、まあね。フルネームの表現は抽象的に考えてたら空白区切りの文字列ですから(ゴミ) UtilやConstantsほど身の危険を感じるobjectもなかなかない。※自分がレビュワーなら即rejectする。 ここまでひどいコードはなかなかないかもしれないが、多分UtilとかConstantsがあるやつは似たようなコードが絶対あると思う。 多分、古いJavaとかの時代だと結構前処理が面倒だったりして使い所あったのだろうけど(知らんけど、それでも、自分ならなるたけ書かないかなぁ。)、Scalaの場合はそんな面倒なコードに(ちゃんと書けば)ならないのでまず要らない。 大体そういう状況はクラス設計が適切じゃないから同じ知識がUtilとなって散在してしまっていることがほとんどだと思う。
  4. まあ一番感じたのは、リクエストとレスポンスのモデル複数箇所で使ってしまっていたときでしたね。 いやまあ、これは共通化できているとは言えないのだけれど。 UtilとかConstantsがあるとき大体クソ。
  5. とか
  6. 関数の引数にフラグを書くのはフラグ引数っていう有名なアンンチパターンですね。 詳細Clean Codeの「においと経験則」を参照
  7. そもそもデータクラスと機能クラスに分ける設計は「クラス」本来の使い方ではない。 むしろJavaが言語の仕組みとしてクラスを採用した意図とは正反対の使い方 クラスはデータとロジックを一つのプログラミング単位にまとめる仕組み データをインスタンス変数として持ち、そのインスタンス変数を使った判断/加工/計算のロジックをメソッドに書くのが、クラス本来の使い方。
  8. インスタンス変数があって、そしてメソッドがある。 振る舞いを表現している。 これは簡単な例だからそりゃそうだろって思うかもしれないけど、実際のプロダクトレベルだとできてないコードは非常に多い。
  9. 先ほどの例のような設計にしないための視点を紹介します。
  10. なんとなき、手続的な設計が良くないことは伝わったと思います。 ただ、(僕の例がアレなこともあって)伝わり切ってない気がしますので、いい設計にするために必要な2つの視点を紹介します。
  11. 凝集度はアプリケーション設計の勉強をしていると必ず出てきてかつなかなか説明が見つからない概念です。そしてすごく重要。
  12. 参考 https://qiita.com/j5ik2o/items/a64007c6d7a89ec2e086 もう中古でしか手に入らない感じだけど、オブジェクトデザインって本に責務の定義は書いてある。
  13. DDDコミュニティを主宰しているログラスの松岡さんの定期ツイートが分かりやすいので紹介します。
  14. 水洗トイレを想像しながら最低限の仕様を考えました。
  15. 機能に着目するとこのような実装になる。 さっきのStringUtilのような実装ですね。 利用者は水洗トイレだと思って使おうとするが、用を足すための穴は空いておらず、流し方もわからない。 まさか、自分で一旦床(メモリ上)に糞を出し、トイレと書かれた箱に入っている壺にそれを入れて、流すにはトイレ箱を川に持っていって流さなければならないとは思わないだろう。
  16. 本を積んで保管するのはトイレの責務ではありません。
  17. トイレが水や糞尿を保持するタンクを持ち、トイレに対して糞尿をすることができ、流すことができる。 そのオブジェクトが何をするのかを表現する必要がある。
  18. それぞれの詳細については記載の書籍に書かれています。 増田さん本の内容やイベントで話ている印象だと、こういったアプリケーション設計を現場に浸透させるには極端さが必要だと思っている節があります。 自分もそっち派で、やはり緩いコードレビューでは浸透しないですし、まずは大袈裟に極端にやって、そこから段々と自然体になっていくものだと思ってます。
  19. やりがちがだけど
  20. http://xerial.org/scala-cookbook/recipes/2012/06/29/enumeration DNAとか生物的なものがあってるかは知りません。
  21. これは例割愛します。