Slide 1

Slide 1 text

【連続講座】ソフトウェア設計原則 【 SOLID 】を学ぶ #3 依存性逆転の原則(dependency inversion principle ) パーソルクロステクノロジー株式会社 第1 技術開発本部 第4 設計部 設計2 課 阿部耕二

Slide 2

Slide 2 text

目次 自己紹介 SOLID について 依存性逆転の原則(dependency inversion principle )について テーマについて 原則違反の例 原則に則った例 依存性注入 今回の設計所感 設計についてのディスカッション・質問 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #3 依存性逆転の原則 2

Slide 3

Slide 3 text

参考資料 3

Slide 4

Slide 4 text

自己紹介 名前: 阿部 耕二(あべ こうじ) 所属: パーソルクロステクノロジー株式会社 第1 技術開発本部 第4 設計部 設計2 課 医療機器の組込みソフトウェア開発。C 言語。 趣味: 宇宙開発(リーマンサットプロジェクト広報メンバー) LAPRAS ポートフォリオ: https://lapras.com/public/k-abe Twitter: @juraruming 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #3 依存性逆転の原則 4

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

SOLID 原則の重要性 凝集度が高くなる 他のモジュールと疎結合になる 各モジュールの目的が明確に分けられると、コード変更の際の影響 は局所化される。結果、テストしやすい設計になる。 上記の特徴を持つと再利用しやすいコードになる。 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #3 依存性逆転の原則 参考資料2 より引用 “ “ 6

Slide 7

Slide 7 text

依存性逆転の原則( dependency inversion principle )について 上位レベルのモジュールは下位レベルのモジュールに依存しないよ うにする。 上位も下位も抽象に依存すべきである。 まず、用語について認識合わせしましょう。 上位とは? 下位とは? 抽象とは? 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #3 依存性逆転の原則 7

Slide 8

Slide 8 text

■ 上位レベル・下位レベルのモジュールとは? 上位レベルは目的を示す 下位レベルは上位の目的を達成する手段を実装する ■ 抽象とは? 下位・上位に共通する概念 この後の章のテーマの説明で触れます。 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #3 依存性逆転の原則 8

Slide 9

Slide 9 text

テーマについて ■ テーマ: 仮空の医療モニタ。患者の生体情報をモニタリングできる。 今回は設定値の書込み・読込み機能について注目する。 ■ テーマの要件: 画面から装置の設定ができる 設定値の例 表示エリア選択、表示テキストの名称・色、画面の輝度、音量、音 の種類、センサの校正値(ゲイン・オフセット)、その他いろいろ 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #3 依存性逆転の原則 9

Slide 10

Slide 10 text

■ テーマの要件(続き): 起動時に前回設定値を装置に反映する。 設定値は持ち運べる(装置の設定状態をPC で見れる) ■ テーマを実現する要素技術: ● 前回設定値の反映 SRAM の設定値を電池でバックアップ ● 設定値の持ち運び SD カード書込み・読込み 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #3 依存性逆転の原則 10

Slide 11

Slide 11 text

■ 今後想定される要素技術の変更: ● 前回設定値の反映 (現状)SRAM を電池にてバックアップ ⇒SPI 接続のシリアルRAM へ ⇒MRAM でバックアップ電池不要へ ● 設定値の持ち運び (現状)SD カード書込み・読込み ⇒USB メモリへの変更 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #3 依存性逆転の原則 11

Slide 12

Slide 12 text

前回設定値の反映 設定値の持ち運び この機能の抽象概念は何か? 共通する概念は何か? ⇒設定値を書く、読むこと 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #3 依存性逆転の原則 12

Slide 13

Slide 13 text

■ 設定値読み・書きの上位・下位モジュールは? 【下位モジュール】 設定値を書く、読むを実現する具体的手段 ● 前回設定値の反映 (現状)SRAM への書込み・読込み SPI 接続のシリアルRAM へ MRAM ● 設定値の持ち運び (現状)SD カードへの書込み・読込み USB メモリへの書込み・読込み 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #3 依存性逆転の原則 13

Slide 14

Slide 14 text

■ 設定値読み・書きの上位・下位モジュールは? 【上位モジュール】 抽象:設定値を書く・読むことを利用するモジュール ● 前回設定値の反映 上位モジュールは起動時に抽象を呼び出し、設定値を反映する 上位モジュールは設定値変更をSRAM に書き込む ● 設定値の持ち運び 上位モジュールはSD カード書込みの画面メニューを選択・実行でSD カード書込みを行なう 上位モジュールはSD カード読込みの画面メニューを選択・実行でSD カード読込みを行なう 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #3 依存性逆転の原則 14

Slide 15

Slide 15 text

● 前回設定値の反映 上位:Boot 起動時に前回設定値を反映し たい 抽象:設定値 設定値の読み・書きの抽象 下位:RAM, MRAM, SpiRAM 実際に設定値を読み・書きす る手段を提供する 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ 15

Slide 16

Slide 16 text

● 設定値の持ち運び 上位:Boot 画面操作されたら設定値の読 み・書きをする 抽象:設定値 設定値の読み・書きの抽象 下位:USBMemory, SDCard 実際に設定値を読み・書きす る手段を提供する 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ 16

Slide 17

Slide 17 text

原則違反の例 【前回設定値の反映】機能の クラス図 上位が下位モジュールに依存 する場合 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ 17

Slide 18

Slide 18 text

前ページのクラス図のコード 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

Slide 19

Slide 19 text

// 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

Slide 20

Slide 20 text

// SettingValueRam.cpp #include "SettingValueRam.h" // コンストラクタの実装 SettingValueRam::SettingValueRam() { } void SettingValueRam::write() { } int SettingValueRam::read() { return 123; } 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #3 依存性逆転の原則 20

Slide 21

Slide 21 text

// SettingValueRam.h #ifndef _H_SETTINGVALUERAM_ #define _H_SETTINGVALUERAM_ class SettingValueRam { private: public: SettingValueRam(); void write(); int read(); }; #endif // _H_SETTINGVALUERAM_ 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #3 依存性逆転の原則 21

Slide 22

Slide 22 text

#include 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

Slide 23

Slide 23 text

原則違反のクラス図・ソースコード 何が課題になるでしょう??? 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #3 依存性逆転の原則 23

Slide 24

Slide 24 text

課題の一例 関心の分離ができていない 目的と目的を達成する手段が混在する。結果、低凝集になる。 目的:起動時に設定値を読む 目的達成手段:RAM に書き込まれている設定値を読む 上位モジュールは下位モジュールがないと動かない 組込みソフトウェア開発では下位モジュールがないことの方が多い (ハードウェアができていない、機材が開発メンバー分がないなど の理由)。 下位モジュールの完成を待っていては開発スケジュールに影響がで る。 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #3 依存性逆転の原則 24

Slide 25

Slide 25 text

コードが汚れる 上位モジュールは下位モジュールがないと動かないから下位モジュ ールの動作を差し替えるテストコードを用意した、とする。 上位モジュールに本番用コードとテスト用コードを切り替える本番 コードには不要な分岐のロジックが実装されソースコードが汚れ る。 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #3 依存性逆転の原則 25

Slide 26

Slide 26 text

コードが汚れる例 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

Slide 27

Slide 27 text

// 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

Slide 28

Slide 28 text

// SettingValueRamFake.cpp #include "SettingValueRamFake.h" // コンストラクタの実装 SettingValueRamFake::SettingValueRamFake() { } void SettingValueRamFake::write() { } int SettingValueRamFake::read() { return 456; } 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #3 依存性逆転の原則 28

Slide 29

Slide 29 text

// 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

Slide 30

Slide 30 text

Boot.cpp の実装を見ると下位モジュール(SettingValueRam) か下位モジ ュールのテストモジュール(SettingValueRamFake) を使うかで分岐が 増えている。 この分岐は本番コードには不要なコードである。 上位モジュールが下位モジュールに依存している場合で、下位モジュ ールをテストしようとするとこんなことがおきる。 コードも汚くなるし、テストしにくい構造になっている。 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #3 依存性逆転の原則 30

Slide 31

Slide 31 text

原則に則った例 【前回設定値の反映】機能の クラス図 原則に則り、上位・下位も抽 象に依存する場合 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ 31

Slide 32

Slide 32 text

上位・下位も抽象に依存する 前ページのクラス図を実装する。 GitHub URL: dip_principle ポイント: 抽象はC++ の仮想関数でInterface のように使う(ISettingValue.h) 下位モジュールはISettingValue を使う(SettingValueRam.h) 上位モジュールは下位モジュールではなく、ISettingValue をメンバ 変数として持つ 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #3 依存性逆転の原則 32

Slide 33

Slide 33 text

// ISettingValue.h #ifndef _H_ISETTINGVALUE_ #define _H_ISETTINGVALUE_ #include 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

Slide 34

Slide 34 text

// 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

Slide 35

Slide 35 text

// 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

Slide 36

Slide 36 text

// Boot.cpp #include "Boot.h" #include "SettingValueRam.h" #include 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

Slide 37

Slide 37 text

実行結果 $ ./dip_principle.app Boot constructor SettingValueRam constructor SettingValue = 123 Boot destructor SettingValueRam decstructor ISettingValue destructor 余計なプリント文が出力されているが、実行結果は原則違反コードの 時と同じ。 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #3 依存性逆転の原則 37

Slide 38

Slide 38 text

Factory でインスタンスを生成する GitHub URL: dip_principle_factories 前回のコードは課題がある。 さて、どこでしょう??? 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #3 依存性逆転の原則 38

Slide 39

Slide 39 text

// Boot.h #include "Boot.h" #include "SettingValueRam.h" #include 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

Slide 40

Slide 40 text

上位モジュールは下位モジュールに依存しないようにするのが依存性 逆転の原則だが、上位モジュールは下位モジュールの依存を断ち切れ ていなかった これを改善していく。 使うテクニックはデザインパターンでお馴染みのFactory 。 Factory クラスのメソッドでインスタンス生成を行う。 こうすることで上位メソッドは下位メソッドとの依存をなくすことが できる。 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #3 依存性逆転の原則 40

Slide 41

Slide 41 text

// Boot.cpp #include "Boot.h" //#include "SettingValueRam.h" #include "Factories.h" #include 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

Slide 42

Slide 42 text

// 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

Slide 43

Slide 43 text

// 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

Slide 44

Slide 44 text

実行結果 $ ./dip_principle_factories.app SettingValue = 123 ファクトリで生成する下位モジュールをSettingValueRamFake に切り 替えた場合 実行結果 $ ./dip_principle_factories.app SettingValue = 456 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #3 依存性逆転の原則 44

Slide 45

Slide 45 text

下位モジュールSettingValueRamFake の実装 // SettingValueRamFake.cpp #include "SettingValueRamFake.h" #include 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

Slide 46

Slide 46 text

依存性注入 前回の【Factory でインスタンスを生成する】で上位モジュールは下位 モジュールとの依存をなくすことができた。 前回のコードを依存性注入のテクニックを使い、よりオブジェクト指 向っぽくする。 オブジェクト指向っぽいとはどういうことか? 後で書きます。 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #3 依存性逆転の原則 46

Slide 47

Slide 47 text

// 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

Slide 48

Slide 48 text

// Boot.cpp #include "Boot.h" //#include "SettingValueRam.h" //#include "Factories.h" #include "ISettingValue.h" #include 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

Slide 49

Slide 49 text

↑ の【オブジェクト指向っぽい】とはどういうことか? システムの中でクラスは自分の責務・責任を果たすために動く。 システムの中の要求で自分の責務だけで目的を達成できないときは、 他のクラスと協調して動く( 私にはこれがオブジェクト指向っぽいと感 じた訳です) 。 依存性注入はクラスが自分の責務を果たすために必要な情報を与えて いる。依存性の注入というワードに惑わされるかもしれないが、至極 当然というか自然なテクニック。 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #3 依存性逆転の原則 前回のコードを依存性注入のテクニックを使い、よりオブジェク ト指向っぽくする。 “ “ 49

Slide 50

Slide 50 text

依存性注入とテスト 依存性注入でテストをやってみる。 テストのシナリオ: 下位モジュールが読み出した設定値が正しいかテストしたい 設定値の確認を行うクラス, メソッド:SettingValueValidation, validate 読み出した設定値は100 以上であれば正しいとする 下位モジュールの設定値はモック・SettingValueMock でテストに適 した値にする 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #3 依存性逆転の原則 50

Slide 51

Slide 51 text

GitHub: dip_and_di_test_easy_env // SettingValueValidation.cpp 下位モジュールが読み出した値の検証 #include "SettingValueValidation.h" #include "ISettingValue.h" #include 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

Slide 52

Slide 52 text

// 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

Slide 53

Slide 53 text

// SettingValueMock.cpp 下位モジュールの設定値読み・書きをモックする #include "SettingValueMock.h" #include 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

Slide 54

Slide 54 text

// SettingValueExampleTest.cpp テスト #include "CppUTest/TestHarness.h" #include 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

Slide 55

Slide 55 text

// テストの結果表示 $ ./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

Slide 56

Slide 56 text

今回の設計所感 未来のことは分からないけど、製品にバリエーションを持たせる必 要が開発開始時にわかっているなら( もしくは多品種にシリーズ展開 する目論みで開発をスタートさせるなど) 依存性逆転の原則を使うと 幸せになれるかもしれないと思った。 開発しているソフトウェアはどういうビジネス戦略で、今後どうい った方針をとるのか、は把握しておいた方がよさそうと感じた。あ とは製品のトレンドとか。やはりビジネスの観点とソフトウェア設 計は関係している、と思った。 原則に則り、依存性注入を使うとテストしやすくなりそう。 原則に則ると製品、プロダクトの拡張にも対応しやすそう。 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #3 依存性逆転の原則 56

Slide 57

Slide 57 text

設計についてのディスカッション・質 問 自分以外の設計の視点が学びになると個人的に考えています。 ぜひぜひお気軽にフィードバックをよろしくお願いします こちらに学習の振り返りに使う目的でZenn のスクラップを用意しま した。 活用ください。 【SOLID 原則】#3 " 依存性逆転の原則(dependency inversion principle )" の勉強会後の振り返り 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #3 依存性逆転の原則 57

Slide 58

Slide 58 text

参考資料 1. オブジェクト指向の原則3:依存関係逆転の原則とインタフェース 分離の原則 Udemy の講座。作成者はピーコック アンダーソンさん。依存関係逆 転の原則以外のSOLID 原則の講座もあり。 2. オブジェクト指向習得のための5ステップ【SOLID 原則】 3. テスト駆動開発による組み込みプログラミング―C 言語とオブジェク ト指向で学ぶアジャイルな設計 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #3 依存性逆転の原則 58

Slide 59

Slide 59 text

ご清聴ありがとうございました 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #3 依存性逆転の原則 59