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

耕二 阿部
耕二 阿部パーソルクロステクノロジー - 一般 em パーソルクロステクノロジー
【連続講座】ソフトウェア設計原則
【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 de 59

Recomendados

ソフトウェア設計原則【SOLID】を学ぶ #4 開放閉鎖の原則.pdf por
ソフトウェア設計原則【SOLID】を学ぶ #4 開放閉鎖の原則.pdfソフトウェア設計原則【SOLID】を学ぶ #4 開放閉鎖の原則.pdf
ソフトウェア設計原則【SOLID】を学ぶ #4 開放閉鎖の原則.pdf耕二 阿部
11 visualizações60 slides
ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle).pdf por
ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle).pdfソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle).pdf
ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle).pdf耕二 阿部
13 visualizações33 slides
ソフトウェア設計原則【SOLID】を学ぶ #5 リスコフの置換原則 por
ソフトウェア設計原則【SOLID】を学ぶ #5 リスコフの置換原則ソフトウェア設計原則【SOLID】を学ぶ #5 リスコフの置換原則
ソフトウェア設計原則【SOLID】を学ぶ #5 リスコフの置換原則耕二 阿部
12 visualizações64 slides
Androidテスティング実践3 ユニットテスト・CI編 por
Androidテスティング実践3 ユニットテスト・CI編Androidテスティング実践3 ユニットテスト・CI編
Androidテスティング実践3 ユニットテスト・CI編株式会社 NTTテクノクロス
4.1K visualizações48 slides
はじめてのCodeIgniter por
はじめてのCodeIgniterはじめてのCodeIgniter
はじめてのCodeIgniterYuya Matsushima
6.4K visualizações65 slides
Lambda: A Peek Under The Hood [Java Day Tokyo 2015 6-3] por
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 visualizações71 slides

Mais conteúdo relacionado

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

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

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

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

Mais de 耕二 阿部

SWEST25_EmbLT_NervesとSpresenseをHostIFで通信してみた.pdf por
SWEST25_EmbLT_NervesとSpresenseをHostIFで通信してみた.pdfSWEST25_EmbLT_NervesとSpresenseをHostIFで通信してみた.pdf
SWEST25_EmbLT_NervesとSpresenseをHostIFで通信してみた.pdf耕二 阿部
3 visualizações23 slides
20210830 rust入学式 por
20210830 rust入学式20210830 rust入学式
20210830 rust入学式耕二 阿部
1.1K visualizações47 slides
Arduinoでモーター制御ロジックを実装した話 por
Arduinoでモーター制御ロジックを実装した話Arduinoでモーター制御ロジックを実装した話
Arduinoでモーター制御ロジックを実装した話耕二 阿部
42 visualizações19 slides
Rust初心者がArduinoをLチカしてみた por
Rust初心者がArduinoをLチカしてみたRust初心者がArduinoをLチカしてみた
Rust初心者がArduinoをLチカしてみた耕二 阿部
411 visualizações18 slides
はじめてのブラシレスモータ制御 por
はじめてのブラシレスモータ制御はじめてのブラシレスモータ制御
はじめてのブラシレスモータ制御耕二 阿部
217 visualizações30 slides
20201029 モデルベース開発モーター制御編~C言語とSimulinkの文法記述を比較する~ por
20201029 モデルベース開発モーター制御編~C言語とSimulinkの文法記述を比較する~20201029 モデルベース開発モーター制御編~C言語とSimulinkの文法記述を比較する~
20201029 モデルベース開発モーター制御編~C言語とSimulinkの文法記述を比較する~耕二 阿部
193 visualizações60 slides

Mais de 耕二 阿部(9)

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

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