---
title: ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle)
tags:  #設計 #solid #単一責務の原則  
author: [k-abe@組み込みソフトウェアの人](https://convert.docswell.com/user/juraruming)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/47MV8XMP7W.jpg?width=480
description: 2023/7/20(木)社内勉強会、2023/7/21(金)Twitterスペースの資料です。 学習の振り返り・深掘りにZennのスクラップを用意しました。ご利用ください。 https://zenn.dev/k_abe/scraps/9533a6f533dd8a
published: July 20, 23
canonical: https://convert.docswell.com/s/juraruming/K98M19-2023-07-20-143150
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/47MV8XMP7W.jpg)

【連続講座】ソフトウェア設計原則
【SOLID】を学ぶ
単一責務の原則(single-responsibility principle)
パーソルクロステクノロジー株式会社
第1技術開発本部 第4設計部 設計2課 阿部耕二
#1
2023 @juraruming


# Page. 2

![Page Image](https://bcdn.docswell.com/page/P7R25NVYJ9.jpg)

目次
自己紹介
SOLID について
単一責務の原則(single-responsibility principle)について
テーマ説明
原則違反のコード例
原則違反のコード改善例
設計についてのディスカッション・質問
今回の設計所感
参考資料
2


# Page. 3

![Page Image](https://bcdn.docswell.com/page/PJXDKNZ4EX.jpg)

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


# Page. 4

![Page Image](https://bcdn.docswell.com/page/3JKX5N8PED.jpg)

【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle)
SOLID
について
設計の5原則の頭文字をとったもの。
S 単一責務の原則（ Single Respomsibility Principle ）
O オープン・クローズドの原則（ Open Closed Principle ）
L リスコフの置換原則（ Liskov Substitution Principle ）
I インターフェイス分離の原則（ Interface Segregation Principle ）
D 依存関係逆転の原則（ Dependency Inversion Principle ）
4


# Page. 5

![Page Image](https://bcdn.docswell.com/page/LE35KV24J5.jpg)

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


# Page. 6

![Page Image](https://bcdn.docswell.com/page/8EDD38Z5EG.jpg)

【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle)
単一責務の原則(single-responsibility
principle)について
参考資料2より引用
モジュールは単一の責務を持つようにする。
モジュールはひとつのことだけをすべきであり、変更の理由もひと
つであるべきということ。
単一責務の原則を適用するとモジュールの凝集度が高くなる。
まとまりのあるひとつの目的を持つ関数とデータから構成されるモ
ジュールになる。
“
“
6


# Page. 7

![Page Image](https://bcdn.docswell.com/page/V7PX48DDE8.jpg)

【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle)
テーマ説明
趣味で開発した連射測定ゲームをテーマにする。
連射測定ゲームとは???
私の少年時代の1980年後半に流行ったシュウォッチをマイコンボード
で再現したもの。
動画はこちら
7


# Page. 8

![Page Image](https://bcdn.docswell.com/page/2JVLXN1G7Q.jpg)

【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle)
ゲーム実行画面
8


# Page. 9

![Page Image](https://bcdn.docswell.com/page/5EGXVK8DJL.jpg)

【連続講座】ソフトウェア設計原則【SOLID】を学ぶ
ゲーム環境紹介
メインボード
Spresense 拡張ボード
Spresense
9


# Page. 10

![Page Image](https://bcdn.docswell.com/page/4JQ86N9X7P.jpg)

【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle)
ゲーム環境紹介２
APS
学習ボード: このボードにLED, スイッチが実装されている
10


# Page. 11

![Page Image](https://bcdn.docswell.com/page/K7424GX2J1.jpg)

【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle)
ゲーム環境紹介3
Spresense
メインボード + 拡張ボード + APS学習ボード
11


# Page. 12

![Page Image](https://bcdn.docswell.com/page/LJ1M4DNKEG.jpg)

【連続講座】ソフトウェア設計原則【SOLID】を学ぶ
マイコン内部ブロッ
ク図
のプロセッサ
の内部ブロック図
こちらから引用
Spresense
CXD5602
12


# Page. 13

![Page Image](https://bcdn.docswell.com/page/GJW3XY4PJ2.jpg)

【連続講座】ソフトウェア設計原則【SOLID】を学ぶ
マイコン ソフトウ
ェアフレームワーク
の構造
こちらから引用
Spresense SDK
13


# Page. 14

![Page Image](https://bcdn.docswell.com/page/4EZV6X26J3.jpg)

【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle)
原則違反のコード例
対象コード:
https://github.com/grace2riku/spresense_game/tree/main/shooting_
watch
shooting_watch_main.c
shooting_watch_gpio.c
14


# Page. 15

![Page Image](https://bcdn.docswell.com/page/Y76524VLEV.jpg)

【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle)
概要のクラス図
15


# Page. 16

![Page Image](https://bcdn.docswell.com/page/G75Y2QDM74.jpg)

【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle)
原則違反コードの改善ポイント1
1.
ファイル名から責務が想像できない
ファイル名から処理内容が想像できたほうが良い。
shooting_watch_gpio.c では GPIO を超えた上位の知識を持ってい
る。
LED の名称（ USER_LED1, USER_LED2 ）、スイッチの名称（ SW1,
SW2 ）を知っているのは上位のモジュールでよい。 LED 、スイッチ
などのデバイスがマイコンのどのピンに接続されているか知ってい
るのは下位のソフトウェアモジュールというのが自然。
上位は下位より抽象的な概念を扱う（下位は具体的）。
16


# Page. 17

![Page Image](https://bcdn.docswell.com/page/9J2G4P8RJR.jpg)

【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle)
原則違反コードの改善ポイント1 ソースコード
学習ボードピンアサイン
// APS
#define SWITCH_1
#define SWITCH_2
(39)
(29)
void shooting_watch_gpio_create(void)
{
/*
*/
board_gpio_intconfig(SWITCH_1, INT_FALLING_EDGE,
board_gpio_intconfig(SWITCH_2, INT_FALLING_EDGE,
割り込み設定
true, shooting_watch_gpio_switch_1_handler);
true, shooting_watch_gpio_switch_2_handler);
if (board_gpio_int(SWITCH_1, true) &lt; 0) {
message(&quot;gpio_create board_gpio_int(switch_1) failure.\n&quot;);
}
if (board_gpio_int(SWITCH_2, true) &lt; 0) {
message(&quot;gpio_create board_gpio_int(switch_2) failure.\n&quot;);
}
return;
}
17


# Page. 18

![Page Image](https://bcdn.docswell.com/page/DEYVM565EM.jpg)

【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle)
原則違反コードの改善ポイント2
2. shooting_watch_gpio.c
はGPIOデバイスドライバーとしての責務を
超えている
デバイスドライバーは上位からの指示でデバイス制御することで再
利用しやすくなる。
デバイスドライバーの中に割り込みハンドラが書かれている。デバ
イスドライバ単体で再利用しにくい。割り込みハンドラにはデバイ
スドライバより抽象的なアプリケーションロジックを書きたいこと
もある。
デバイスドライバより上位の層に割り込みハンドラを書けるように
デバイスドライバは関数仕様を考えた方が使い勝手がよさそう。
18


# Page. 19

![Page Image](https://bcdn.docswell.com/page/VJNMWNZ478.jpg)

【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle)
原則違反コードの改善ポイント2 ソースコード
static int shooting_watch_gpio_switch_1_handler(int irq, FAR void *context, FAR void *arg)
{
++shooting_count;
return 0;
}
static int shooting_watch_gpio_switch_2_handler(int irq, FAR void *context, FAR void *arg)
{
int sw2_status = board_gpio_read(SWITCH_2);
int sw1_status = board_gpio_read(SWITCH_1);
if (sw1_status &amp;&amp; !sw2_status) next_state = true;
if (!sw1_status &amp;&amp; !sw2_status) exit_shooting_watch = true;
return 0;
}
19


# Page. 20

![Page Image](https://bcdn.docswell.com/page/YE9NXRZ4E3.jpg)

【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle)
原則違反コードの改善ポイント3
関数でハードウェアアクセス関数を呼び出している
責務を意識せず作り込みしソフトウェアの階層を無視している。
アプリケーションは実現方法(ハードウェアの具体的制御)を意識し
ないつくりが良い。
アプリケーション部でハードウェアアクセスすると非常に再利用し
にくいコードになる。
3. main
20


# Page. 21

![Page Image](https://bcdn.docswell.com/page/GE8K2W1V7D.jpg)

【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle)
原則違反コードの改善ポイント3 ソースコード
int main(int argc, FAR char *argv[])
{
int one_time_counter = 0;
int game_coundown;
shooting_watch_gpio_create();
printf(&quot;Hello, shooting_watch!!!\n&quot;);
while(exit_shooting_watch != true) {
switch (game_state) {
case STOP:
if (one_time_counter == 0) {
printf(&quot;----- Press SW2 to start the game. When the game starts, shoot SW1 continuously.-----\n&quot;);
printf(&quot;----- Press SW1 and SW2 to end the game.-----\n&quot;);
one_time_counter = 1;
board_gpio_write(USER_LED_1, USER_LED_TURN_OFF);
board_gpio_write(USER_LED_2, USER_LED_TURN_OFF);
}
21


# Page. 22

![Page Image](https://bcdn.docswell.com/page/LELZ2NQRJR.jpg)

【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle)
原則違反のコード改善例
対象コード:
https://github.com/grace2riku/spresense_game/tree/refactoring_srp/
shooting_watch
aps_lerning_board_bsp.c, aps_lerning_board_bsp.h
controller.c, controller.h
game.c, game.h
initialize.c, initialize.h
main.c
shooting_count.c, shooting_count.h
22


# Page. 23

![Page Image](https://bcdn.docswell.com/page/4JMV8X1PJW.jpg)

改善クラス図
23


# Page. 24

![Page Image](https://bcdn.docswell.com/page/PJR25NLYE9.jpg)

【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle)
【再掲】原則違反コードの改善ポイント1
1.
ファイル名から責務が想像できない
ファイル名から処理内容が想像できたほうが良い。
shooting_watch_gpio.c では GPIO を超えた上位の知識を持ってい
る。
LED の名称（ USER_LED1, USER_LED2 ）、スイッチの名称（ SW1,
SW2 ）を知っているのは上位のモジュールでよい。 LED 、スイッチ
などのデバイスがマイコンのどのピンに接続されているか知ってい
るのは下位のソフトウェアモジュールというのが自然。
上位は下位より抽象的な概念を扱う（下位は具体的）。
24


# Page. 25

![Page Image](https://bcdn.docswell.com/page/PEXDKNW47X.jpg)

【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle)
改善ポイント1の改善内容
ファイル名から責務が想像できるようにファイル名変更、分割をお
こなった
-&gt; 改善クラス図を参照
部品の名称を知っているモジュール、部品のピン番号をしっている
モジュールを明確にした
部品の名称はaps_lerning_board_bsp.hに定義し公開する。
ピン番号はaps_lerning_board_bsp.cに実装しヘッダーファイルで公
開しないようにした。
25


# Page. 26

![Page Image](https://bcdn.docswell.com/page/3EKX5NVP7D.jpg)

【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle)
【再掲】原則違反コードの改善ポイント2
2. shooting_watch_gpio.c
はGPIOデバイスドライバーとしての責務を
超えている
デバイスドライバーは上位からの指示でデバイス制御することで再
利用しやすくなる。
デバイスドライバーの中に割り込みハンドラが書かれている。デバ
イスドライバ単体で再利用しにくい。割り込みハンドラにはデバイ
スドライバより抽象的なアプリケーションロジックを書きたいこと
もある。
デバイスドライバより上位の層に割り込みハンドラを書けるように
デバイスドライバは関数仕様を考えた方が使い勝手がよさそう。
26


# Page. 27

![Page Image](https://bcdn.docswell.com/page/L735KVM4E5.jpg)

【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle)
改善ポイント2の改善内容
、スイッチの制御はaps_lerning_board_bspのled_onoff,
のみから行う方針にした。
割り込みハンドラはデバイスドライバではなく、上位の層に定義し
た
LED
read_user_switch
controller -&gt; nextstate_and_exit_interrupt
ゲーム開始・終了のスイッチ操作の割り込み
shooting_count -&gt; shooting_count_interrupt
連射測定の割り込み
27


# Page. 28

![Page Image](https://bcdn.docswell.com/page/87DD38657G.jpg)

【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle)
【再掲】原則違反コードの改善ポイント3
関数でハードウェアアクセス関数を呼び出している
責務を意識せず作り込みしソフトウェアの階層を無視している。
アプリケーションは実現方法(ハードウェアの具体的制御)を意識し
ないつくりが良い。
アプリケーション部でハードウェアアクセスすると非常に再利用し
にくいコードになる。
3. main
28


# Page. 29

![Page Image](https://bcdn.docswell.com/page/VJPX48YD78.jpg)

【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle)
改善ポイント3の改善内容
階層構造と責務の分担を意識してクラス図を書いた
上の層はゲームの目的を達成するロジックを担当する部分
下の層はゲームの目的を達成するための具体的な手段を担当するよ
う意識した。
29


# Page. 30

![Page Image](https://bcdn.docswell.com/page/2EVLXNGGJQ.jpg)

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


# Page. 31

![Page Image](https://bcdn.docswell.com/page/57GXV5DDEL.jpg)

【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle)
今回の設計所感
階層化を意識してファイル分割、責務分割をしたつもり。階層化の
デメリットとして高速な動作を求められる場合は改善が必要だと感
じた。
設計する際は性能などの非機能要件を考慮することも大事だと改め
て認識した。
31


# Page. 32

![Page Image](https://bcdn.docswell.com/page/4EQ86Z1XJP.jpg)

【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle)
参考資料
オブジェクト指向習得のための５ステップ【SOLID原則】
2. テスト駆動開発による組み込みプログラミング ―C 言語とオブジェク
ト指向で学ぶアジャイルな設計
1.
32


# Page. 33

![Page Image](https://bcdn.docswell.com/page/KJ4243R2E1.jpg)

【連続講座】ソフトウェア設計原則【SOLID】を学ぶ #1 単一責務の原則(single-responsibility principle)
ご清聴ありがとうございました
2023 @juraruming
33


