ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則.pdf

耕二 阿部
耕二 阿部パーソルクロステクノロジー - 一般 at パーソルクロステクノロジー
【連続講座】ソフトウェア設計原則
【SOLID】を学ぶ
#3 依存性逆転の原則(dependency inversion principle)
パーソルクロステクノロジー株式会社
第1技術開発本部 第4設計部 設計2課 阿部耕二
目次
自己紹介
SOLIDについて
依存性逆転の原則(dependency inversion principle)について
テーマについて
原則違反の例
原則に則った例
依存性注入
今回の設計所感
設計についてのディスカッション・質問
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
2
参考資料
3
自己紹介
名前: 阿部 耕二(あべ こうじ)
所属: パーソルクロステクノロジー株式会社
第1技術開発本部第4設計部設計2課
医療機器の組込みソフトウェア開発。C言語。
趣味: 宇宙開発(リーマンサットプロジェクト広報メンバー)
LAPRASポートフォリオ: https://lapras.com/public/k-abe
Twitter: @juraruming
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
4
SOLIDについて
設計の5原則の頭文字をとったもの。
S 単一責務の原則(Single Respomsibility Principle)
O オープン・クローズドの原則(Open Closed Principle)
L リスコフの置換原則(Liskov Substitution Principle)
I インターフェイス分離の原則(Interface Segregation Principle)
D 依存関係逆転の原則(Dependency Inversion Principle)
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
5
SOLID原則の重要性
凝集度が高くなる
他のモジュールと疎結合になる
各モジュールの目的が明確に分けられると、コード変更の際の影響
は局所化される。結果、テストしやすい設計になる。
上記の特徴を持つと再利用しやすいコードになる。
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
参考資料2より引用
“
“
6
依存性逆転の原則(dependency
inversion principle)について
上位レベルのモジュールは下位レベルのモジュールに依存しないよ
うにする。
上位も下位も抽象に依存すべきである。
まず、用語について認識合わせしましょう。
上位とは?
下位とは?
抽象とは?
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
7
■ 上位レベル・下位レベルのモジュールとは?
上位レベルは目的を示す
下位レベルは上位の目的を達成する手段を実装する
■抽象とは?
下位・上位に共通する概念
この後の章のテーマの説明で触れます。
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
8
テーマについて
■テーマ:
仮空の医療モニタ。患者の生体情報をモニタリングできる。
今回は設定値の書込み・読込み機能について注目する。
■テーマの要件:
画面から装置の設定ができる
設定値の例
表示エリア選択、表示テキストの名称・色、画面の輝度、音量、音
の種類、センサの校正値(ゲイン・オフセット)、その他いろいろ
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
9
■テーマの要件(続き):
起動時に前回設定値を装置に反映する。
設定値は持ち運べる(装置の設定状態をPCで見れる)
■テーマを実現する要素技術:
●前回設定値の反映
SRAMの設定値を電池でバックアップ
●設定値の持ち運び
SDカード書込み・読込み
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
10
■今後想定される要素技術の変更:
●前回設定値の反映
(現状)SRAMを電池にてバックアップ
⇒SPI接続のシリアルRAMへ
⇒MRAMでバックアップ電池不要へ
●設定値の持ち運び
(現状)SDカード書込み・読込み
⇒USBメモリへの変更
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
11
前回設定値の反映
設定値の持ち運び
この機能の抽象概念は何か?
共通する概念は何か?
⇒設定値を書く、読むこと
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
12
■設定値読み・書きの上位・下位モジュールは?
【下位モジュール】
設定値を書く、読むを実現する具体的手段
● 前回設定値の反映
(現状)SRAMへの書込み・読込み
SPI接続のシリアルRAMへ
MRAM
● 設定値の持ち運び
(現状)SDカードへの書込み・読込み
USBメモリへの書込み・読込み
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
13
■設定値読み・書きの上位・下位モジュールは?
【上位モジュール】
抽象:設定値を書く・読むことを利用するモジュール
● 前回設定値の反映
上位モジュールは起動時に抽象を呼び出し、設定値を反映する
上位モジュールは設定値変更をSRAMに書き込む
● 設定値の持ち運び
上位モジュールはSDカード書込みの画面メニューを選択・実行でSD
カード書込みを行なう
上位モジュールはSDカード読込みの画面メニューを選択・実行でSD
カード読込みを行なう
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
14
● 前回設定値の反映
上位:Boot
起動時に前回設定値を反映し
たい
抽象:設定値
設定値の読み・書きの抽象
下位:RAM, MRAM, SpiRAM
実際に設定値を読み・書きす
る手段を提供する
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ
15
● 設定値の持ち運び
上位:Boot
画面操作されたら設定値の読
み・書きをする
抽象:設定値
設定値の読み・書きの抽象
下位:USBMemory, SDCard
実際に設定値を読み・書きす
る手段を提供する
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ
16
原則違反の例
【前回設定値の反映】機能の
クラス図
上位が下位モジュールに依存
する場合
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ
17
前ページのクラス図のコード
GitHub URL: no_dip_principle
// Boot.cpp
#include "Boot.h"
// コンストラクタの実装
Boot::Boot() {
_settingValue = new SettingValueRam();
}
Boot::~Boot() {
delete _settingValue;
}
int Boot::readSettingValue() {
return _settingValue->read();
}
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
18
// Boot.h
#ifndef _H_BOOT_
#define _H_BOOT_
#include "SettingValueRam.h"
class Boot {
private:
SettingValueRam* _settingValue;
public:
Boot();
~Boot();
int readSettingValue();
};
#endif // _H_BOOT_
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
19
// SettingValueRam.cpp
#include "SettingValueRam.h"
// コンストラクタの実装
SettingValueRam::SettingValueRam() {
}
void SettingValueRam::write() {
}
int SettingValueRam::read() {
return 123;
}
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
20
// SettingValueRam.h
#ifndef _H_SETTINGVALUERAM_
#define _H_SETTINGVALUERAM_
class SettingValueRam {
private:
public:
SettingValueRam();
void write();
int read();
};
#endif // _H_SETTINGVALUERAM_
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
21
#include <iostream>
using namespace std;
#include "Boot.h"
int main() {
Boot* boot = new Boot();
cout << "SettingValue = " << boot->readSettingValue() << endl;
delete boot;
return 0;
}
実行結果
$ ./no_dip_principle.app
SettingValue = 123
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
22
原則違反のクラス図・ソースコード
何が課題になるでしょう???
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
23
課題の一例
関心の分離ができていない
目的と目的を達成する手段が混在する。結果、低凝集になる。
目的:起動時に設定値を読む
目的達成手段:RAMに書き込まれている設定値を読む
上位モジュールは下位モジュールがないと動かない
組込みソフトウェア開発では下位モジュールがないことの方が多い
(ハードウェアができていない、機材が開発メンバー分がないなど
の理由)。
下位モジュールの完成を待っていては開発スケジュールに影響がで
る。
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
24
コードが汚れる
上位モジュールは下位モジュールがないと動かないから下位モジュ
ールの動作を差し替えるテストコードを用意した、とする。
上位モジュールに本番用コードとテスト用コードを切り替える本番
コードには不要な分岐のロジックが実装されソースコードが汚れ
る。
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
25
コードが汚れる例GitHub URL: no_dip_principle_dirty
// Boot.cpp
#include "Boot.h"
// コンストラクタの実装
Boot::Boot() {
if (settingValueSelect) {
_settingValue = new SettingValueRam();
} else {
_settingValueRamFake = new SettingValueRamFake();
}
}
Boot::~Boot() {
if (settingValueSelect) {
delete _settingValue;
} else {
delete _settingValueRamFake;
}
}
int Boot::readSettingValue() {
if (settingValueSelect) {
return _settingValue->read();
} else {
return _settingValueRamFake->read();
}
}
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
26
// Boot.h
#ifndef _H_BOOT_
#define _H_BOOT_
#include "SettingValueRam.h"
#include "SettingValueRamFake.h"
class Boot {
private:
SettingValueRam* _settingValue;
SettingValueRamFake* _settingValueRamFake;
public:
int settingValueSelect = 0;
Boot();
~Boot();
int readSettingValue();
};
#endif // _H_BOOT_
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
27
// SettingValueRamFake.cpp
#include "SettingValueRamFake.h"
// コンストラクタの実装
SettingValueRamFake::SettingValueRamFake() {
}
void SettingValueRamFake::write() {
}
int SettingValueRamFake::read() {
return 456;
}
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
28
// SettingValueRamFake.h
#ifndef _H_SETTINGVALUERAMFAKE_
#define _H_SETTINGVALUERAMFAKE_
class SettingValueRamFake {
private:
public:
SettingValueRamFake();
void write();
int read();
};
#endif // _H_SETTINGVALUERAMFAKE_
実行結果
$ ./no_dip_principle_dirty.app
SettingValue = 456
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
29
Boot.cppの実装を見ると下位モジュール(SettingValueRam)か下位モジ
ュールのテストモジュール(SettingValueRamFake)を使うかで分岐が
増えている。
この分岐は本番コードには不要なコードである。
上位モジュールが下位モジュールに依存している場合で、下位モジュ
ールをテストしようとするとこんなことがおきる。
コードも汚くなるし、テストしにくい構造になっている。
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
30
原則に則った例
【前回設定値の反映】機能の
クラス図
原則に則り、上位・下位も抽
象に依存する場合
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ
31
上位・下位も抽象に依存する
前ページのクラス図を実装する。
GitHub URL: dip_principle
ポイント:
抽象はC++の仮想関数でInterfaceのように使う(ISettingValue.h)
下位モジュールはISettingValueを使う(SettingValueRam.h)
上位モジュールは下位モジュールではなく、ISettingValueをメンバ
変数として持つ
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
32
// ISettingValue.h
#ifndef _H_ISETTINGVALUE_
#define _H_ISETTINGVALUE_
#include <iostream>
using namespace std;
class ISettingValue {
public:
virtual void write() = 0;
virtual int read() = 0;
// 仮想デストラクタ
virtual ~ISettingValue(){
cout << "ISettingValue destructor" << endl;
}
};
#endif // _H_ISETTINGVALUE_
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
33
// SettingValueRam.h
#ifndef _H_SETTINGVALUERAM_
#define _H_SETTINGVALUERAM_
#include "ISettingValue.h"
class SettingValueRam : public ISettingValue {
private:
public:
SettingValueRam();
~SettingValueRam();
void write();
int read();
};
#endif // _H_SETTINGVALUERAM_
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
34
// Boot.h
#ifndef _H_BOOT_
#define _H_BOOT_
#include "ISettingValue.h"
class Boot {
private:
ISettingValue* _settingValue;
public:
Boot();
~Boot();
int readSettingValue();
};
#endif // _H_BOOT_
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
35
// Boot.cpp
#include "Boot.h"
#include "SettingValueRam.h"
#include <iostream>
using namespace std;
// コンストラクタの実装
Boot::Boot() {
cout << "Boot constructor" << endl;
_settingValue = new SettingValueRam();
}
Boot::~Boot() {
cout << "Boot destructor" << endl;
delete _settingValue;
}
int Boot::readSettingValue() {
return _settingValue->read();
}
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
36
実行結果
$ ./dip_principle.app
Boot constructor
SettingValueRam constructor
SettingValue = 123
Boot destructor
SettingValueRam decstructor
ISettingValue destructor
余計なプリント文が出力されているが、実行結果は原則違反コードの
時と同じ。
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
37
Factoryでインスタンスを生成する
GitHub URL: dip_principle_factories
前回のコードは課題がある。
さて、どこでしょう???
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
38
// Boot.h
#include "Boot.h"
#include "SettingValueRam.h"
#include <iostream>
using namespace std;
// コンストラクタの実装
Boot::Boot() {
cout << "Boot constructor" << endl;
_settingValue = new SettingValueRam(); // ★ここで下位モジュールに依存している
}
Boot::~Boot() {
cout << "Boot destructor" << endl;
delete _settingValue;
}
int Boot::readSettingValue() {
return _settingValue->read();
}
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
39
上位モジュールは下位モジュールに依存しないようにするのが依存性
逆転の原則だが、上位モジュールは下位モジュールの依存を断ち切れ
ていなかった
これを改善していく。
使うテクニックはデザインパターンでお馴染みのFactory。
Factoryクラスのメソッドでインスタンス生成を行う。
こうすることで上位メソッドは下位メソッドとの依存をなくすことが
できる。
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
40
// Boot.cpp
#include "Boot.h"
//#include "SettingValueRam.h"
#include "Factories.h"
#include <iostream>
using namespace std;
// コンストラクタの実装
Boot::Boot() {
cout << "Boot constructor" << endl;
_settingValue = Factories::CreateSettingValue();
}
Boot::~Boot() {
cout << "Boot destructor" << endl;
delete _settingValue;
}
int Boot::readSettingValue() {
return _settingValue->read();
}
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
41
// Factories.h
#ifndef _H_FACTORIES_
#define _H_FACTORIES_
#include "ISettingValue.h"
#include "SettingValueRam.h"
class Factories {
public:
static ISettingValue* CreateSettingValue();
};
#endif // _H_FACTORIES_
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
42
// Factories.cpp
#include "Factories.h"
#include "ISettingValue.h"
#include "SettingValueRam.h"
#include "SettingValueRamFake.h"
ISettingValue* Factories::CreateSettingValue() {
return new SettingValueRam();
// return new SettingValueRamFake();
}
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
43
実行結果
$ ./dip_principle_factories.app
SettingValue = 123
ファクトリで生成する下位モジュールをSettingValueRamFakeに切り
替えた場合
実行結果
$ ./dip_principle_factories.app
SettingValue = 456
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
44
下位モジュールSettingValueRamFakeの実装
// SettingValueRamFake.cpp
#include "SettingValueRamFake.h"
#include <iostream>
using namespace std;
// コンストラクタの実装
SettingValueRamFake::SettingValueRamFake() {
cout << "SettingValueRamFake constructor" << endl;
}
SettingValueRamFake::~SettingValueRamFake() {
cout << "SettingValueRamFake decstructor" << endl;
}
void SettingValueRamFake::write() {
}
int SettingValueRamFake::read() {
return 456;
}
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
45
依存性注入
前回の【Factoryでインスタンスを生成する】で上位モジュールは下位
モジュールとの依存をなくすことができた。
前回のコードを依存性注入のテクニックを使い、よりオブジェクト指
向っぽくする。
オブジェクト指向っぽいとはどういうことか?後で書きます。
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
46
// Boot.h
#ifndef _H_BOOT_
#define _H_BOOT_
#include "ISettingValue.h"
class Boot {
private:
ISettingValue* _settingValue;
public:
Boot(ISettingValue* settingValue); // ★ここに注目!!!
~Boot();
int readSettingValue();
};
#endif // _H_BOOT_
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
47
// Boot.cpp
#include "Boot.h"
//#include "SettingValueRam.h"
//#include "Factories.h"
#include "ISettingValue.h"
#include <iostream>
using namespace std;
// コンストラクタの実装
Boot::Boot(ISettingValue* settingValue) {
cout << "Boot constructor" << endl;
// _settingValue = Factories::CreateSettingValue();
_settingValue = settingValue;
}
Boot::~Boot() {
cout << "Boot destructor" << endl;
delete _settingValue;
}
int Boot::readSettingValue() {
return _settingValue->read();
}
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
48
↑の【オブジェクト指向っぽい】とはどういうことか?
システムの中でクラスは自分の責務・責任を果たすために動く。
システムの中の要求で自分の責務だけで目的を達成できないときは、
他のクラスと協調して動く(私にはこれがオブジェクト指向っぽいと感
じた訳です)。
依存性注入はクラスが自分の責務を果たすために必要な情報を与えて
いる。依存性の注入というワードに惑わされるかもしれないが、至極
当然というか自然なテクニック。
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
前回のコードを依存性注入のテクニックを使い、よりオブジェク
ト指向っぽくする。
“
“
49
依存性注入とテスト
依存性注入でテストをやってみる。
テストのシナリオ:
下位モジュールが読み出した設定値が正しいかテストしたい
設定値の確認を行うクラス, メソッド:SettingValueValidation,
validate
読み出した設定値は100以上であれば正しいとする
下位モジュールの設定値はモック・SettingValueMockでテストに適
した値にする
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
50
GitHub: dip_and_di_test_easy_env
// SettingValueValidation.cpp 下位モジュールが読み出した値の検証
#include "SettingValueValidation.h"
#include "ISettingValue.h"
#include <iostream>
using namespace std;
// コンストラクタの実装
SettingValueValidation::SettingValueValidation(ISettingValue* settingValue) {
cout << "SettingValueValidation constructor" << endl;
_settingValue = settingValue;
}
SettingValueValidation::~SettingValueValidation() {
cout << "SettingValueValidation destructor" << endl;
delete _settingValue;
}
bool SettingValueValidation::validate() {
int value = _settingValue->read();
if (value >= 100) return true;
return false;
}
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
51
// SettingValueValidation.h
#ifndef _H_SETTINGVALUEVALIDATION_
#define _H_SETTINGVALUEVALIDATION_
#include "ISettingValue.h"
class SettingValueValidation {
private:
ISettingValue* _settingValue;
public:
SettingValueValidation(ISettingValue* settingValue);
~SettingValueValidation();
bool validate();
};
#endif // _H_SETTINGVALUEVALIDATION_
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
52
// SettingValueMock.cpp 下位モジュールの設定値読み・書きをモックする
#include "SettingValueMock.h"
#include <iostream>
using namespace std;
// コンストラクタの実装
SettingValueMock::SettingValueMock() {
cout << "SettingValueMock constructor" << endl;
}
SettingValueMock::~SettingValueMock() {
cout << "SettingValueMock decstructor" << endl;
}
void SettingValueMock::write() {
}
int SettingValueMock::read() {
return 100;
}
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
53
// SettingValueExampleTest.cpp テスト
#include "CppUTest/TestHarness.h"
#include <iostream>
using namespace std;
#include "SettingValueValidation.h"
#include "SettingValueMock.h"
#include "ISettingValue.h"
TEST_GROUP(SettingValueExampleTest)
{
SettingValueValidation* settingValueValidation;
void setup()
{
// モック(SettingValueMock)を設定値チェックのロジック(SettingValueValidation)に依存性注入している
settingValueValidation = new SettingValueValidation(new SettingValueMock());
}
void teardown()
{
delete settingValueValidation;
}
};
TEST(SettingValueExampleTest, SettingValueValid)
{
CHECK(settingValueValidation->validate());
}
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
54
// テストの結果表示
$ ./bin/dip_and_di_test_easy_env -v
TEST(SettingValueExampleTest, SettingValueValid)
- 0 ms
OK (1 tests, 1 ran, 1 checks, 0 ignored, 0 filtered out, 1 ms)
依存性注入を使うことでテストコード、本番コードの切り替えも簡
単に行える
下位モジュールはデバイス制御に特化したコードにする(今回の例で
は設定値の読み出しのみ)。下位モジュールを使う上位モジュールの
ロジックをテストしやすくなる。
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
55
今回の設計所感
未来のことは分からないけど、製品にバリエーションを持たせる必
要が開発開始時にわかっているなら(もしくは多品種にシリーズ展開
する目論みで開発をスタートさせるなど)依存性逆転の原則を使うと
幸せになれるかもしれないと思った。
開発しているソフトウェアはどういうビジネス戦略で、今後どうい
った方針をとるのか、は把握しておいた方がよさそうと感じた。あ
とは製品のトレンドとか。やはりビジネスの観点とソフトウェア設
計は関係している、と思った。
原則に則り、依存性注入を使うとテストしやすくなりそう。
原則に則ると製品、プロダクトの拡張にも対応しやすそう。
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
56
設計についてのディスカッション・質
問
自分以外の設計の視点が学びになると個人的に考えています。
ぜひぜひお気軽にフィードバックをよろしくお願いします
こちらに学習の振り返りに使う目的でZennのスクラップを用意しま
した。
活用ください。
【SOLID原則】#3 "依存性逆転の原則(dependency inversion
principle)"の勉強会後の振り返り
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
57
参考資料
1. オブジェクト指向の原則3:依存関係逆転の原則とインタフェース
分離の原則
Udemyの講座。作成者はピーコックアンダーソンさん。依存関係逆
転の原則以外のSOLID原則の講座もあり。
2. オブジェクト指向習得のための5ステップ【SOLID原則】
3. テスト駆動開発による組み込みプログラミング―C言語とオブジェク
ト指向で学ぶアジャイルな設計
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
58
ご清聴ありがとうございました
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則
59
1 of 59

Recommended

ソフトウェア設計原則【SOLID】を学ぶ #4 開放閉鎖の原則.pdf by
ソフトウェア設計原則【SOLID】を学ぶ #4 開放閉鎖の原則.pdfソフトウェア設計原則【SOLID】を学ぶ #4 開放閉鎖の原則.pdf
ソフトウェア設計原則【SOLID】を学ぶ #4 開放閉鎖の原則.pdf耕二 阿部
11 views60 slides
ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle).pdf by
ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle).pdfソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle).pdf
ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle).pdf耕二 阿部
15 views33 slides
ソフトウェア設計原則【SOLID】を学ぶ #5 リスコフの置換原則 by
ソフトウェア設計原則【SOLID】を学ぶ #5 リスコフの置換原則ソフトウェア設計原則【SOLID】を学ぶ #5 リスコフの置換原則
ソフトウェア設計原則【SOLID】を学ぶ #5 リスコフの置換原則耕二 阿部
12 views64 slides
Androidテスティング実践3 ユニットテスト・CI編 by
Androidテスティング実践3 ユニットテスト・CI編Androidテスティング実践3 ユニットテスト・CI編
Androidテスティング実践3 ユニットテスト・CI編株式会社 NTTテクノクロス
4.1K views48 slides
はじめてのCodeIgniter by
はじめてのCodeIgniterはじめてのCodeIgniter
はじめてのCodeIgniterYuya Matsushima
6.4K views65 slides
Lambda: A Peek Under The Hood [Java Day Tokyo 2015 6-3] by
Lambda: A Peek Under The Hood [Java Day Tokyo 2015 6-3]Lambda: A Peek Under The Hood [Java Day Tokyo 2015 6-3]
Lambda: A Peek Under The Hood [Java Day Tokyo 2015 6-3]David Buck
155 views71 slides

More Related Content

Similar to ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則.pdf

Androidテスティング実践2 システムテスト編 by
Androidテスティング実践2 システムテスト編Androidテスティング実践2 システムテスト編
Androidテスティング実践2 システムテスト編株式会社 NTTテクノクロス
3.6K views64 slides
LLVM overview 20110122 by
LLVM overview 20110122LLVM overview 20110122
LLVM overview 20110122nothingcosmos
2.8K views32 slides
PHP勉強会 #51 by
PHP勉強会 #51PHP勉強会 #51
PHP勉強会 #51Takako Miyagawa
3.5K views56 slides
ワンクリックデプロイ101 #ocdeploy by
ワンクリックデプロイ101 #ocdeployワンクリックデプロイ101 #ocdeploy
ワンクリックデプロイ101 #ocdeployRyutaro YOSHIBA
12.9K views123 slides
テストからより良い組込みソフトウェア開発を考える.pdf by
テストからより良い組込みソフトウェア開発を考える.pdfテストからより良い組込みソフトウェア開発を考える.pdf
テストからより良い組込みソフトウェア開発を考える.pdf耕二 阿部
4 views51 slides
Howtoよいデザイン by
HowtoよいデザインHowtoよいデザイン
HowtoよいデザインHiroki Yagita
1.4K views56 slides

Similar to ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則.pdf(20)

LLVM overview 20110122 by nothingcosmos
LLVM overview 20110122LLVM overview 20110122
LLVM overview 20110122
nothingcosmos2.8K views
ワンクリックデプロイ101 #ocdeploy by Ryutaro YOSHIBA
ワンクリックデプロイ101 #ocdeployワンクリックデプロイ101 #ocdeploy
ワンクリックデプロイ101 #ocdeploy
Ryutaro YOSHIBA12.9K views
テストからより良い組込みソフトウェア開発を考える.pdf by 耕二 阿部
テストからより良い組込みソフトウェア開発を考える.pdfテストからより良い組込みソフトウェア開発を考える.pdf
テストからより良い組込みソフトウェア開発を考える.pdf
耕二 阿部4 views
Howtoよいデザイン by Hiroki Yagita
HowtoよいデザインHowtoよいデザイン
Howtoよいデザイン
Hiroki Yagita1.4K views
FSLogix アプリケーションマスク機能実験結果 by Dai Iwai
FSLogix アプリケーションマスク機能実験結果FSLogix アプリケーションマスク機能実験結果
FSLogix アプリケーションマスク機能実験結果
Dai Iwai233 views
Web applicationpenetrationtest その5 by Tetsuya Hasegawa
Web applicationpenetrationtest その5Web applicationpenetrationtest その5
Web applicationpenetrationtest その5
Tetsuya Hasegawa745 views
【Ltech#10】LIFULL HOME'S ネイティブアプリ用APIのデプロイを自動化する by LIFULL Co., Ltd.
【Ltech#10】LIFULL HOME'S ネイティブアプリ用APIのデプロイを自動化する【Ltech#10】LIFULL HOME'S ネイティブアプリ用APIのデプロイを自動化する
【Ltech#10】LIFULL HOME'S ネイティブアプリ用APIのデプロイを自動化する
LIFULL Co., Ltd.624 views
【アシアル塾】PHPオブジェクト指向再入門・第四回デザインパターンに学ぶクラス設計 by アシアル株式会社
【アシアル塾】PHPオブジェクト指向再入門・第四回デザインパターンに学ぶクラス設計【アシアル塾】PHPオブジェクト指向再入門・第四回デザインパターンに学ぶクラス設計
【アシアル塾】PHPオブジェクト指向再入門・第四回デザインパターンに学ぶクラス設計
Visual Studio App Centerを公式サンプルアプリから学ぼうiOS(swift),Android(java) by Shinya Nakajima
Visual Studio App Centerを公式サンプルアプリから学ぼうiOS(swift),Android(java)Visual Studio App Centerを公式サンプルアプリから学ぼうiOS(swift),Android(java)
Visual Studio App Centerを公式サンプルアプリから学ぼうiOS(swift),Android(java)
Shinya Nakajima7.7K views
.NET micro FrameWork for TOPPERS (.NET基礎)@基礎勉強会 by Kiyoshi Ogawa
.NET micro  FrameWork for TOPPERS  (.NET基礎)@基礎勉強会.NET micro  FrameWork for TOPPERS  (.NET基礎)@基礎勉強会
.NET micro FrameWork for TOPPERS (.NET基礎)@基礎勉強会
Kiyoshi Ogawa1.7K views
Bindingからframework elementを見つける by Tatsuya Ishikawa
Bindingからframework elementを見つけるBindingからframework elementを見つける
Bindingからframework elementを見つける
Tatsuya Ishikawa6.2K views
20141224 titech lecture_ishizaki_public by Kazuaki Ishizaki
20141224 titech lecture_ishizaki_public20141224 titech lecture_ishizaki_public
20141224 titech lecture_ishizaki_public
Kazuaki Ishizaki949 views
Appsody でnodejsのアプリを立ち上げよう! by Daisuke Hiraoka
Appsody でnodejsのアプリを立ち上げよう!Appsody でnodejsのアプリを立ち上げよう!
Appsody でnodejsのアプリを立ち上げよう!
Daisuke Hiraoka274 views
iOSやAndroidアプリ開発のGoodPractice by Ken Morishita
iOSやAndroidアプリ開発のGoodPracticeiOSやAndroidアプリ開発のGoodPractice
iOSやAndroidアプリ開発のGoodPractice
Ken Morishita12.4K views
第4回勉強会 単体テストのすすめ by hakoika-itwg
第4回勉強会 単体テストのすすめ第4回勉強会 単体テストのすすめ
第4回勉強会 単体テストのすすめ
hakoika-itwg9.4K views
はこだてIKA 第4回勉強会 単体テスト by Seiji KOMATSU
はこだてIKA 第4回勉強会 単体テストはこだてIKA 第4回勉強会 単体テスト
はこだてIKA 第4回勉強会 単体テスト
Seiji KOMATSU785 views
ビジネス的に高価値なアジャイルテスト by Tsutomu Chikuba
ビジネス的に高価値なアジャイルテストビジネス的に高価値なアジャイルテスト
ビジネス的に高価値なアジャイルテスト
Tsutomu Chikuba2.1K views

More from 耕二 阿部

SWEST25_EmbLT_NervesとSpresenseをHostIFで通信してみた.pdf by
SWEST25_EmbLT_NervesとSpresenseをHostIFで通信してみた.pdfSWEST25_EmbLT_NervesとSpresenseをHostIFで通信してみた.pdf
SWEST25_EmbLT_NervesとSpresenseをHostIFで通信してみた.pdf耕二 阿部
3 views23 slides
20210830 rust入学式 by
20210830 rust入学式20210830 rust入学式
20210830 rust入学式耕二 阿部
1.1K views47 slides
Arduinoでモーター制御ロジックを実装した話 by
Arduinoでモーター制御ロジックを実装した話Arduinoでモーター制御ロジックを実装した話
Arduinoでモーター制御ロジックを実装した話耕二 阿部
43 views19 slides
Rust初心者がArduinoをLチカしてみた by
Rust初心者がArduinoをLチカしてみたRust初心者がArduinoをLチカしてみた
Rust初心者がArduinoをLチカしてみた耕二 阿部
412 views18 slides
はじめてのブラシレスモータ制御 by
はじめてのブラシレスモータ制御はじめてのブラシレスモータ制御
はじめてのブラシレスモータ制御耕二 阿部
218 views30 slides
20201029 モデルベース開発モーター制御編~C言語とSimulinkの文法記述を比較する~ by
20201029 モデルベース開発モーター制御編~C言語とSimulinkの文法記述を比較する~20201029 モデルベース開発モーター制御編~C言語とSimulinkの文法記述を比較する~
20201029 モデルベース開発モーター制御編~C言語とSimulinkの文法記述を比較する~耕二 阿部
193 views60 slides

More from 耕二 阿部(9)

SWEST25_EmbLT_NervesとSpresenseをHostIFで通信してみた.pdf by 耕二 阿部
SWEST25_EmbLT_NervesとSpresenseをHostIFで通信してみた.pdfSWEST25_EmbLT_NervesとSpresenseをHostIFで通信してみた.pdf
SWEST25_EmbLT_NervesとSpresenseをHostIFで通信してみた.pdf
耕二 阿部3 views
20210830 rust入学式 by 耕二 阿部
20210830 rust入学式20210830 rust入学式
20210830 rust入学式
耕二 阿部1.1K views
Arduinoでモーター制御ロジックを実装した話 by 耕二 阿部
Arduinoでモーター制御ロジックを実装した話Arduinoでモーター制御ロジックを実装した話
Arduinoでモーター制御ロジックを実装した話
耕二 阿部43 views
Rust初心者がArduinoをLチカしてみた by 耕二 阿部
Rust初心者がArduinoをLチカしてみたRust初心者がArduinoをLチカしてみた
Rust初心者がArduinoをLチカしてみた
耕二 阿部412 views
はじめてのブラシレスモータ制御 by 耕二 阿部
はじめてのブラシレスモータ制御はじめてのブラシレスモータ制御
はじめてのブラシレスモータ制御
耕二 阿部218 views
20201029 モデルベース開発モーター制御編~C言語とSimulinkの文法記述を比較する~ by 耕二 阿部
20201029 モデルベース開発モーター制御編~C言語とSimulinkの文法記述を比較する~20201029 モデルベース開発モーター制御編~C言語とSimulinkの文法記述を比較する~
20201029 モデルベース開発モーター制御編~C言語とSimulinkの文法記述を比較する~
耕二 阿部193 views
モデルベース開発勉強会 by 耕二 阿部
モデルベース開発勉強会モデルベース開発勉強会
モデルベース開発勉強会
耕二 阿部293 views
EVミニカート、技術交流&ミニセミナ 発表資料 by 耕二 阿部
EVミニカート、技術交流&ミニセミナ 発表資料EVミニカート、技術交流&ミニセミナ 発表資料
EVミニカート、技術交流&ミニセミナ 発表資料
耕二 阿部73 views
AWSとEVカートで走行データを可視化 by 耕二 阿部
AWSとEVカートで走行データを可視化AWSとEVカートで走行データを可視化
AWSとEVカートで走行データを可視化
耕二 阿部182 views

ソフトウェア設計原則【SOLID】を学ぶ #3 依存性逆転の原則.pdf