Slide 1

Slide 1 text

【連続講座】ソフトウェア設計原則 【 SOLID 】を学ぶ #2 インターフェイス分離の原則(Interface segregation principle ) パーソルクロステクノロジー株式会社 第1 技術開発本部 第4 設計部 設計2 課 阿部耕二

Slide 2

Slide 2 text

目次 自己紹介 SOLID について インターフェイス分離の原則(Interface segregation principle )に ついて インターフェイスについて 例1. 複合機 例2. 乗り物 例3. read, write 例4. リングバッファ 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #2 インターフェイス分離の原則 2

Slide 3

Slide 3 text

今回の設計所感 設計についてのディスカッション・質問 参考資料

Slide 4

Slide 4 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

インターフェイス分離の原則 ( Interface segregation principle )に ついて 相手に必要なことだけを見せるようにする。必要ないことを見せる とよくないことがおきる。 本来、関連が必要ないクラスと関連をもってしまったり(疎結合で はなく密結合になる)、 変更の影響が大きくなってしまったりする。 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #2 インターフェイス分離の原則 参考資料1 より引用 “ “ 7

Slide 8

Slide 8 text

インターフェイスについて インターフェイスとは? 機能の使い方のみを定義している。 データ・処理を持たない。 データ・処理をもたないのでそのまま使うことはできない。 インターフェイスの使い方を実現したクラスをインスタンス化して使 う。 インターフェイスは参考資料3 が個人的にわかりやすかった。 Interface クラスの使い方ポイント解説【オブジェクト指向】 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #2 インターフェイス分離の原則 8

Slide 9

Slide 9 text

C++ でインターフェイス実現例 #include #include class Shape { public: virtual void print_type() = 0; virtual float calc_area() = 0; }; class Circle : public Shape { private: float r; public: Circle(float r) { this->r = r;} ~Circle() { } void print_type() { std::cout << "This is circle." << std::endl; } float calc_area() { return this->r * this->r * 3.14; } }; class Triangle : public Shape { private: float base; float height; public: Triangle(float base, float height) {this->base = base; this->height = height;} ~Triangle() { } void print_type() { std::cout << "This is triangle." << std::endl; } float calc_area() { return (this->base * this->height) / 2.0; } }; class Square : public Shape { private: float side; public: Square(float side) {this->side = side;} ~Square() { } void print_type() { std::cout << "This is square." << std::endl; } float calc_area() { return this->side * this->side; } }; 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ 9

Slide 10

Slide 10 text

C++ でインターフェイス実現例(インターフェイスを使う側) int main() { Shape* circle = new Circle(1.2); Shape* triangle = new Triangle(2.5, 2.0); Shape* square = new Square(1.3); circle->print_type(); std::cout << "circle area = " << circle->calc_area() << std::endl; triangle->print_type(); std::cout << "triangle area = " << triangle->calc_area() << std::endl; square->print_type(); std::cout << "square area = " << square->calc_area() << std::endl; } 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #2 インターフェイス分離の原則 10

Slide 11

Slide 11 text

例 1. 複合機 参考資料4 の複合機の例がわか りやすかったので説明に使わ せていただく。 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ 11

Slide 12

Slide 12 text

複合機の例の学び 異なる目的を持つ機能を組み合わせて製品にバリエーションを持た せる、などのときにインターフェイス分離の原則は効果を発揮しそ うだ。 対象を自然な形で表現できる。 インターフェイス分離の原則と単一責務の原則のエッセンスは似て いる。小さい目的の組み合わせでシステムが構成する。 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #2 インターフェイス分離の原則 12

Slide 13

Slide 13 text

例 2. 乗り物 参考資料5 の乗り物のアクショ ンの例がわかりやすかったの で説明に使わせていただく。 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ 13

Slide 14

Slide 14 text

乗り物の例の学び インターフェイスを分離しないことで例の車の飛ぶメソッドのよう に現実とはかけ離れた構造を実現できてしまうので注意が必要。 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #2 インターフェイス分離の原則 14

Slide 15

Slide 15 text

例 3. read, write インタフェース分離の原則で組込みソフトウェア向けのサンプルコー ドをChatGPT に提示してもらいました。 原則違反の例、原則に則った例のコードを提示してもらいました。 IoT の文脈でセンサーデータを読み込み、活用するシステムをイメージ してもらえればと思います。 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #2 インターフェイス分離の原則 15

Slide 16

Slide 16 text

原則違反の例 class IDevice { public: virtual void readData() = 0; virtual void writeData() = 0; virtual void performAction() = 0; }; class Sensor : public IDevice { public: void readData() override { // センサーデータを読み取る処理 } void writeData() override { // センサーデータを保存する処理 } void performAction() override { // センサーの動作を制御する処理 } }; 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #2 インターフェイス分離の原則 16

Slide 17

Slide 17 text

原則に則った例 class IDataReader { public: virtual void readData() = 0; }; class IDataWriter { public: virtual void writeData() = 0; }; class IActionPerformer { public: virtual void performAction() = 0; }; class Sensor : public IDataReader, public IDataWriter, public IActionPerformer { public: void readData() override { // センサーデータを読み取る処理 } void writeData() override { // センサーデータを保存する処理 } void performAction() override { // センサーの動作を制御する処理 } }; 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #2 インターフェイス分離の原則 17

Slide 18

Slide 18 text

データの読み込み、書き込みを分けると組込みソフトウェアの現場で 使いそうな汎用的なパターンになりそうです。 class SensorDataDispley : public IDataReader, public IActionPerformer { public: void readData() override { // センサーデータを読み取る処理 } void performAction() override { // センサーの動作を制御する処理 } }; class SensorDataStore : public IDataWriter { public: void writeData() override { // センサーデータを保存する処理 } }; 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #2 インターフェイス分離の原則 18

Slide 19

Slide 19 text

例 4. リングバッファ インタフェース分離の原則で組込みソフトウェア向けのサンプルコー ドを考えた時にはじめに頭に浮かんだのがリングバッファでした。 インタフェース分離とはリングバッファのライトとリードのインター フェースを分けるような実装かなぁと想像しました。 こちらもChatGPT にコードを提示してもらいました。 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #2 インターフェイス分離の原則 19

Slide 20

Slide 20 text

原則違反の例 class IRingBuffer { public: virtual void enqueue(int data) = 0; virtual int dequeue() = 0; virtual bool isEmpty() = 0; }; class RingBuffer : public IRingBuffer { private: int buffer[100]; int head; int tail; public: void enqueue(int data) override { // データをバッファに追加する処理 } int dequeue() override { // バッファからデータを取り出す処理 return 0; } bool isEmpty() override { // バッファが空かどうかを判定する処理 return true; } }; 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #2 インターフェイス分離の原則 20

Slide 21

Slide 21 text

class Application { public: void processData(IRingBuffer* buffer) { if (!buffer->isEmpty()) { int data = buffer->dequeue(); // データを処理する } } }; int main() { RingBuffer buffer; Application app; // アプリケーションを実行 app.processData(&buffer); return 0; } 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #2 インターフェイス分離の原則 21

Slide 22

Slide 22 text

原則に則った例 class IEnqueuer { public: virtual void enqueue(int data) = 0; }; class IDequeuer { public: virtual int dequeue() = 0; }; class IBufferChecker { public: virtual bool isEmpty() = 0; }; class RingBuffer : public IEnqueuer, public IDequeuer, public IBufferChecker { private: int buffer[100]; int head; int tail; public: void enqueue(int data) override { // データをバッファに追加する処理 } int dequeue() override { // バッファからデータを取り出す処理 return 0; } bool isEmpty() override { // バッファが空かどうかを判定する処理 return true; } }; 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #2 インターフェイス分離の原則 22

Slide 23

Slide 23 text

class Application { public: void processData(IDequeuer* dequeuer, IBufferChecker* checker) { if (!checker->isEmpty()) { int data = dequeuer->dequeue(); // データを処理する } } }; int main() { RingBuffer buffer; Application app; // アプリケーションを実行 app.processData(&buffer, &buffer); return 0; } 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #2 インターフェイス分離の原則 23

Slide 24

Slide 24 text

RingBuffer クラスが分離した3 つのインタフェースを使っている。 エンキュー、デキューでクラスを分けると責務が分かれたクラスが できると感じた。 ただ機械的にインタフェースを分離すれば良いわけではなく、 どんな目的を達成したいからインターフェイスをどのような粒度で分 離しするのか、 そしてどのような責務を持つクラスで目的を実現するのか? 、の思考・ 検討が大事だと感じた。 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #2 インターフェイス分離の原則 24

Slide 25

Slide 25 text

今回の設計所感 インターフェイスはどのくらいの粒度で分離すれば良いのか? -> ひとつヒントになりそうなのは単一責務の原則の視点だと思った。 -> この問いに非常に参考になるのは参考資料6 の動画。 Forkwell エンジニア文化祭2023 「分岐を低減するinterface 設計と発 想の転換」ミノ駆動 目的に注目することがヒントになることを認識できた。 インターフェイス自体の学習にもオススメです。 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #2 インターフェイス分離の原則 25

Slide 26

Slide 26 text

参考資料6 の中で以下の意味合いの内容が印象に残った。 このようなライブラリ・インターフェイスは会社・組織のソフトウェ ア資産となる考えられるのでこのような信頼性高いものを開発したい と思いました。 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #2 インターフェイス分離の原則 標準ライブラリFILE のopen, read, write などは信頼を持って、特 に意識することなくつかっている。 このような信頼性高いライブラリ・インターフェイスを生み出し たいものである。 “ “ 26

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

参考資料 1. オブジェクト指向習得のための5ステップ【SOLID 原則】 2. テスト駆動開発による組み込みプログラミング―C 言語とオブジェク ト指向で学ぶアジャイルな設計 3. Interface クラスの使い方ポイント解説【オブジェクト指向】 4. 【オブジェクト指向】「インターフェース分離の原則」について 5. インターフェース分離の原則とは何か 6. Forkwell エンジニア文化祭2023 「分岐を低減するinterface 設計と 発想の転換」ミノ駆動 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #2 インターフェイス分離の原則 28

Slide 29

Slide 29 text

ご清聴ありがとうございました 【連続講座】ソフトウェア設計原則【SOLID 】を学ぶ #2 インターフェイス分離の原則 29