Posted on: Written by: K-Sato
⚠️ This article was posted over a year go. The information might be outdated. ⚠️

Table of Contents

設計とアーキテクチャ

  • ソフトウェアアーキテクチャの目的は求められるシステムを構築・保守する為に必要な人材を最小限に押さえ込む事
  • 崩壊したコードを書く方がクリーンなコードを書くよりも常に早い(=早く進む唯一の方法はうまく進む事である)

3 つのパラダイム

  • 構造化プログラミング モジュールを証明可能な単位に再帰的に分割可能 テストはバグが存在しない事ではなく、バグが存在することを示すもの。
  • オブジェクト指向プログラミング カプセル化・継承・ポリーモフィズムはオブジェクト指向以前から存在し、使用されていた。 オブジェクト指向とはポリーモフィズムを使用することで、システムにある全てのソースコードの依存関係を絶対的に制御する能力。
  • 関数型プログラミング コンポーネントの分離・データ管理・機能

まとめ

どのパラダイムも何かしらを奪っている。

  • 構造化プログラミングは直接的な制御の以降に規律を課すもの。
  • オブジェクト指向プログラミングは間接的な制御の以降に規律を課すもの。
  • 関数型プログラミングは代入に規律を課すもの。

ソフトウェアの本質は順次・選択・反復・間接参照であり、昔と変わらない。

設計の原則

SOLIDの原則

SOLIDの原則の目的

SOLID の原則の目的は以下のような性質をもつ中間レベルのソフトウェア構造を作ること。

  • 変更に強い
  • 理解しやすい
  • コンポーネントの基盤として多くのソフトウェアで使用可能

SOLID の原則の内容

  • 単一責任の原則(SRP: Single Responsibility Principle) 個々のモジュールを変更する理由がただ1つだけになるよう、ソフトウェアシステムの構造がそれを使用する組織の社会的構造に大きな影響を受けるようにする。
  • オープン・クローズドの原則(OCP: Open-Closed Principle) ソフトウェアを変更しやすくする為に、既存のコードの変更よりも新しいコードの追加によって、システムの振る舞いを変更できるように設計すべきである。
  • リスコフの置き換え原則(LSP: Liskov Substitution Principle) 交換可能なパーツを使ってソフトウェアシステムを構築するなら、個々のパーツが交換可能となるような契約に従わなければいけないこと。
  • インターフェイス分離の原則(ISP: Interface Segregation Principle) 使っていないものへの依存を回避すべきとういう原則。
  • 依存関係逆転の原則(DIP: Dependency Inversion Principle) 上位レベルの方針の実装コードは下位レベルの詳細の実装コードに依存すべきではなく、逆に詳細側が方針に依存すべきであるという原則。

コンポーネントの原則

コンポーネントとはデプロイの単位の事。(Ruby における gem)

コンポーネントの凝縮生

  • 再利用・リリース等価の原則(REP) 再利用の単位とリリースの単位は等価になる。 ソフトウェアを再利用する事、内容を変更してリリースする。 1つのコンポーネントを形成するクラスやモジュールはまとめてリリース可能でなければならない。

  • 閉鎖性共通の原則(CCP) 同じ理由、同じタイミングで変更されるクラスをコンポーネントにまとめること。変更の理由やタイミングが異なるっクラスは別のコンポーネントに分ける事。(単一責任の原則をコンポーネント向けに言い換えたもの) = 同じタイミングで変更される事が多いクラスは1つにまとめておけという事。

  • 全再利用の原則(CRP) コンポーネントのユーザーに対して実際には使わないものへの依存を強要してはいけない。 (インターフェイス分離の原則を一般化したもの。)

image

ソフトウェアアーキテクチャとは?

ソフトウェアアーキテクチャはプログラマである。自分で課題を経験していなければ、他のプログラマの耐えに適切な仕事をする事などできないからだ。 ソフトウェアステムの開発・デプロイ・運用・保守を容易にする事が仕事。最終的な目的としてはシステムのライフタイムコストを最小限に抑え、プログラマの生産性を最大にする事。

Clean Architecture

下記の図の円の内側は方針、外側は仕組みである。

image

依存性のルール

上記の円の中央に近づくほど、ソフトウェアのレベルが上がっていく。 ソースコードの依存性は、内側(上位レベルの方針)だけに向かっていなければならない。 円の内側は外側について何も知らない。特に外側で宣言された名前は、内側にあるコードで触れてはいけない。

エンティティ(ビジネスルール)

最重要ビジネスルールを操作する・含んだものをエンティティと呼ぶ。エンティティのインターフェースはそうしたデータを操作する最重要ビジネスルールを実装した関数で構成されている。 こうしたクラスを作成する際は、ビジネスにとって不可欠な概念を実装するソフトウェアをまとめ、これから構築するシステムから切り離すようにする。つまり、ビジネスを表すものとして、エンティティのクラスを独立させる。

image

ユースケース

  • ユースケースとは自動化されたシステムを使用する方法を記述したもの。
  • ユースケースはアプリケーション固有のビジネスルールを記述している。
  • ユースケースにはエンティティの最重要ビジネスルールをいつ・どのように呼び出すかを規定したルールが含まれている。(ユーザとエンティティのインタラクションを支配するアプリケーションの固有のルールを記述したもの。)
  • ユースケース(下位レベルのコンセプト)はエンティティ(上位レベルのコンセプト)に依存し、エンティティはユースケースに依存しない。

インターフェイスアダプター

ユースケースやエンティティに便利なフォーマットから、データベースやウェブなどの外部エージェントに便利なフォーマットにデータを変換するアダプター。GUI の MVC アーキテクチャを保持するのはこのレイヤーになる。(プレゼンター、ビュー、コントローラは全てこのインタフェイスアダプターのレイヤに属している。モデルはコントローラからユースケースに渡されユースケースからプレゼンターとビューに戻されるデータ構造にすぎない。)

フレームワークとドライバ

最も外側の円はフレームワークやツールで構成される。データベースやウェブフレームワークなどである。 通常、このレイヤにはコードをあまり書かない。

参考

About the author

I am a web-developer based somewhere on earth. I primarily code in TypeScript, Go and Ruby at work. React, RoR and Gin are my go-to Frameworks.