3.8K Views
August 28, 23
スライド概要
2023/8/28(月)に実施する社内勉強会、X スペース 【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #2 インターフェイス分離の原則(Interface segregation principle)" の資料です。
組込みソフトウェアエンジニア。 技術バックボーンはC言語・ベアメタル。 CQ EVカートのオーナーで、ハード・ソフトウェアの改造を通じて自身のスキルアップを日々考え中・・・。 LAPRASポートフォリオ: https://lapras.com/public/k-abe GitHub: http://github.com/grace2riku Qiita: https://qiita.com/juraruming Zenn: https://zenn.dev/k_abe よろしくね。
【連続講座】ソフトウェア設計原則 【SOLID】を学ぶ #2 インターフェイス分離の原則(Interface segregation principle) パーソルクロステクノロジー株式会社 第1技術開発本部 第4設計部 設計2課 阿部耕二
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #2 インターフェイス分離の原則 目次 自己紹介 SOLID について インターフェイス分離の原則(Interface segregation principle)に ついて インターフェイスについて 例1. 複合機 例2. 乗り物 例3. read, write 例4. リングバッファ 2
今回の設計所感 設計についてのディスカッション・質問 参考資料
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #2 インターフェイス分離の原則 自己紹介 名前: 阿部 耕二(あべ こうじ) 所属: パーソルクロステクノロジー株式会社 第1技術開発本部 第4設計部 設計2課 医療機器の組込みソフトウェア開発。C言語。 趣味: 宇宙開発(リーマンサットプロジェクト広報メンバー) LAPRAS ポートフォリオ : https://lapras.com/public/k-abe Twitter: @juraruming 4
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #2 インターフェイス分離の原則 SOLID について 設計の5原則の頭文字をとったもの。 S 単一責務の原則( Single Respomsibility Principle ) O オープン・クローズドの原則( Open Closed Principle ) L リスコフの置換原則( Liskov Substitution Principle ) I インターフェイス分離の原則( Interface Segregation Principle ) D 依存関係逆転の原則( Dependency Inversion Principle ) 5
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #2 インターフェイス分離の原則 SOLID 原則の重要性 参考資料2より引用 凝集度が高くなる 他のモジュールと疎結合になる 各モジュールの目的が明確に分けられると、コード変更の際の影響 は局所化される。結果、テストしやすい設計になる。 上記の特徴を持つと再利用しやすいコードになる。 “ “ 6
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #2 インターフェイス分離の原則 インターフェイス分離の原則 (Interface segregation principle)に ついて 相手に必要なことだけを見せるようにする。必要ないことを見せる とよくないことがおきる。 本来、関連が必要ないクラスと関連をもってしまったり(疎結合で はなく密結合になる)、 変更の影響が大きくなってしまったりする。 “ 参考資料 1 より引用 7 “
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #2 インターフェイス分離の原則 インターフェイスについて インターフェイスとは? 機能の使い方のみを定義している。 データ・処理を持たない。 データ・処理をもたないのでそのまま使うことはできない。 インターフェイスの使い方を実現したクラスをインスタンス化して使 う。 インターフェイスは参考資料3が個人的にわかりやすかった。 Interface クラスの使い方ポイント解説【オブジェクト指向】 8
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ
C++
でインターフェイス実現例
#include <iostream>
#include <cstdlib>
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;
}
};
9
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #2 インターフェイス分離の原則
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;
}
10
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ 例1. 複合機 参考資料4の複合機の例がわか りやすかったので説明に使わ せていただく。 11
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #2 インターフェイス分離の原則 複合機の例の学び 異なる目的を持つ機能を組み合わせて製品にバリエーションを持た せる、などのときにインターフェイス分離の原則は効果を発揮しそ うだ。 対象を自然な形で表現できる。 インターフェイス分離の原則と単一責務の原則のエッセンスは似て いる。小さい目的の組み合わせでシステムが構成する。 12
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ 例2. 乗り物 参考資料5の乗り物のアクショ ンの例がわかりやすかったの で説明に使わせていただく。 13
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #2 インターフェイス分離の原則 乗り物の例の学び インターフェイスを分離しないことで例の車の飛ぶメソッドのよう に現実とはかけ離れた構造を実現できてしまうので注意が必要。 14
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #2 インターフェイス分離の原則 例3. read, write インタフェース分離の原則で組込みソフトウェア向けのサンプルコー ドをChatGPTに提示してもらいました。 原則違反の例、原則に則った例のコードを提示してもらいました。 IoT の文脈でセンサーデータを読み込み、活用するシステムをイメージ してもらえればと思います。 15
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #2 インターフェイス分離の原則 原則違反の例 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 { // } センサーの動作を制御する処理 }; 16
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #2 インターフェイス分離の原則 原則に則った例 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 { // } センサーの動作を制御する処理 }; 17
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #2 インターフェイス分離の原則 データの読み込み、書き込みを分けると組込みソフトウェアの現場で 使いそうな汎用的なパターンになりそうです。 class SensorDataDispley : public IDataReader, public IActionPerformer { public: void readData() override { // } void performAction() override { // } }; センサーデータを読み取る処理 センサーの動作を制御する処理 class SensorDataStore : public IDataWriter { public: void writeData() override { // }; センサーデータを保存する処理 } 18
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #2 インターフェイス分離の原則 例4. リングバッファ インタフェース分離の原則で組込みソフトウェア向けのサンプルコー ドを考えた時にはじめに頭に浮かんだのがリングバッファでした。 インタフェース分離とはリングバッファのライトとリードのインター フェースを分けるような実装かなぁと想像しました。 こちらもChatGPTにコードを提示してもらいました。 19
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #2 インターフェイス分離の原則 原則違反の例 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; } バッファが空かどうかを判定する処理 }; 20
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #2 インターフェイス分離の原則
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;
}
21
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #2 インターフェイス分離の原則 原則に則った例 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; } バッファが空かどうかを判定する処理 }; 22
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #2 インターフェイス分離の原則
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;
}
23
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #2 インターフェイス分離の原則 クラスが分離した3つのインタフェースを使っている。 エンキュー、デキューでクラスを分けると責務が分かれたクラスが できると感じた。 ただ機械的にインタフェースを分離すれば良いわけではなく、 どんな目的を達成したいからインターフェイスをどのような粒度で分 離しするのか、 そしてどのような責務を持つクラスで目的を実現するのか?、の思考・ 検討が大事だと感じた。 RingBuffer 24
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #2 インターフェイス分離の原則 今回の設計所感 インターフェイスはどのくらいの粒度で分離すれば良いのか? -> ひとつヒントになりそうなのは単一責務の原則の視点だと思った。 -> この問いに非常に参考になるのは参考資料 6 の動画。 Forkwell エンジニア文化祭 2023 「分岐を低減する interface 設計と発 想の転換」ミノ駆動 目的に注目することがヒントになることを認識できた。 インターフェイス自体の学習にもオススメです。 25
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #2 インターフェイス分離の原則 参考資料6の中で以下の意味合いの内容が印象に残った。 “ 標準ライブラリ FILE の open, read, write などは信頼を持って、特 に意識することなくつかっている。 このような信頼性高いライブラリ・インターフェイスを生み出し たいものである。 このようなライブラリ・インターフェイスは会社・組織のソフトウェ ア資産となる考えられるのでこのような信頼性高いものを開発したい と思いました。 “ 26
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #2 インターフェイス分離の原則 設計についてのディスカッション・質 問 自分以外の設計の視点が学びになると個人的に考えています。 ぜひぜひお気軽にフィードバックをよろしくお願いします こちらに学習の振り返りに使う目的でZennのスクラップを用意しま した。 活用ください。 【SOLID原則】#2 "インターフェイス分離の原則(Interface segregation principle ) " の勉強会後の振り返り 27
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #2 インターフェイス分離の原則 参考資料 オブジェクト指向習得のための5ステップ【SOLID原則】 2. テスト駆動開発による組み込みプログラミング ―C 言語とオブジェク ト指向で学ぶアジャイルな設計 3. Interface クラスの使い方ポイント解説【オブジェクト指向】 4. 【オブジェクト指向】「インターフェース分離の原則」について 5. インターフェース分離の原則とは何か 6. Forkwell エンジニア文化祭 2023 「分岐を低減する interface 設計と 発想の転換」ミノ駆動 1. 28
【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #2 インターフェイス分離の原則 ご清聴ありがとうございました 29