sato's note

技術メモ

Mac + MySQLクライント + Docker + Mariadb

MySQLクライアントのインストール

❯ brew install mysql-client

Mariadbコンテナの作成

❯ docker run -d -e MARIADB_ALLOW_EMPTY_PASSWORD=1 mariadb/server

コンテナの確認

❯ docker ps
CONTAINER ID   IMAGE               COMMAND                  CREATED          STATUS          PORTS                               NAMES
a7252458d78f   mariadb/server      "docker-entrypoint.s…"   5 minutes ago    Up 5 minutes    3306/tcp                            hardcore_wright

mariadbにログイン

❯ docker exec -it hardcore_wright mysql

モノリシックとマイクロサービス

概要

ソフトウェアにおけるモノリシックとは、分割されていない1つのモジュールで構成されたものを指す。

マイクロサービスとは、複数の小さいサービスの集合体から一つのアプリケーションを構成するアーキテクチャの一種。

モノリシックとマイクロサービスは対の関係になる。

モノリシック

図例

f:id:ryo310jp:20200810104651p:plain

@startuml
cloud "Cloud" {
  package "管理画面" {
    [ログイン]
    [商品管理]
    [注文管理]
    [在庫管理]
  }
}

node "Node" {
  database "Database" {
    [アカウント]
    [商品]
    [注文]
    [在庫]
  }
}

[ログイン] .. [アカウント] : TCP
[商品管理] .. [商品] : TCP
[注文管理] .. [注文] : TCP
[在庫管理] .. [在庫] : TCP
@enduml

メリット

  • 一つのプロセスで処理を全てを行う事ができる。
  • 処理速度が高速である(通信コストが最小で済む等の理由で)

デメリット

  • 拡張が難しい。
  • 一つの機能をデプロイする際に他の機能への影響が大きい
  • サービスの担当者は全ての機能を把握する必要がある

マイクロサービス

図例

f:id:ryo310jp:20200810141207p:plain

@startuml
cloud {
  package "管理画面" {
  }
}

cloud {
  package "アカウントAPI" {
    [ログイン]
  }
  database  {
    [アカウント]
  }
}
cloud {
  package "商品API" {
    [商品管理]
  }
  database  {
    [商品]
  }
}
cloud {
  package "注文在庫API" {
    [注文管理]
    [在庫管理]
  }
  database  {
    [注文]
    [在庫]
  }
}

管理画面 .. アカウントAPI: HTTP
管理画面 .. 商品API: HTTP
商品API .. 注文在庫API: HTTP

[ログイン] .. [アカウント] : TCP
[商品管理] .. [商品] : TCP
[注文管理] .. [注文] : TCP
[在庫管理] .. [在庫] : TCP
@enduml

メリット

概要

  • マイクロサービスごとにデプロイできる
  • マイクロサービスごとにスケールできる
  • マイクロサービスごとに適切な技術を自由に選択できる
  • マイクロサービスごとに独立した運用担当チームに任せられる。
  • 開発サイクルの高速化
  • 可用性の向上

詳細

  • サービスごとに個別にスケールできる事で、コストの適正化、スパイクが生じた場合の可用性の維持が可能。
  • サービスごとに独立したチームは各サービスに最適な技術を自由に選択可能
  • サービスごとに独立した複数のチームから構成されるマイクロサービスでは、チームがそれぞれ自分の担当するサービスについて理解が深く、自主的かつ迅速に仕事に取り組める。
  • モノリシックでは1 つのコンポーネントに障害が発生すると、アプリケーション全体に障害が及ぶおそれがある。マイクロサービスでは、一つのコンポーネントへの障害はアプリケーション全体の障害にはならず、機能の低下だけに留まる。

デメリット

  • 通信コストの増加
  • 構成が複雑になるおそれ
  • サービスごとに自由ゆえに統一感をなくすおそれ

出典

https://ec-orange.jp/ec-media/?p=23421

DRYの原則

概要

Don't repeat yourself

直訳:同じコードを重複させるな。

本来の意図:ソフトウェア開発全体において情報を重複させない

DBスキーマ、テスト計画、ビルドシステムや、ドキュメンテーション等、幅広く適用できる。

この原則がうまく適用されたとき、いかなる変更も、関連のない要素の変更にはつながらない。さらに、関連する要素は統一的に変更され、それらの変更は同期が取れたものとなる。

DRY 原則が有用でない場合

  • 冗長化ミラーリング
  • 構成管理
  • 自動生成出力結果:生成コードで重複が排除されていれば良い。結果は重複していても良い。
  • 過度なDRY:一つの関数が引数に応じて振る舞いを変化させる。

出典

qiita.com

ja.wikipedia.org

YAGNIの原則

概要

You ain't gonna need it

機能は実際に必要となるまでは追加しないのがよい

後で使うだろうという予測の元に作ったものの90%は無駄になる。

予期しない変更に対しては、設計を単純にすることが備えとなる。

コードをすばやく実装するために最も良い方法は、あまりコードを書かないことである。そして、バグを減らすために最も良い方法も、あまりコードを書かないことである

出典

ja.wikipedia.org

KISSの原則

概要

Keep It Simple Stupid.(シンプルで愚鈍にする)

以下の様な解釈もある

  • Keep it short and simple
  • Keep it simple, stupid

どちらにしてもシンプルに設計・開発する様にという事。

技術力を見せつける為の様な複雑な設計は要らない。

SOLIDの原則

概要

  • Single Responsibility Principle:単一責任の原則
  • Open/closed principle:オープン/クロースドの原則
  • Liskov substitution principle:リスコフの置換原則
  • Interface segregation principle:インターフェース分離の原則
  • Dependency inversion principle:依存性逆転の原則

Single Responsibility Principle:単一責任の原則

クラスは1つのことだけ責任を負うべき

この原則は以下の様に複数の利用者を想定すると理解しやすい。

  • 1つの利用者の要件変更が別の利用者の既存要件を破壊する
  • 複数の利用者による要件変更により、マージ時にコンフリクトが発生する

つまり、複数の役割を持つモジュールでは複数の利用者の要件を同時に満たせなくなるケースが発生しやすい。

  • プロパティの管理とDBストレージの管理の分割
  • 社員クラスが人事と総務の役割を負うべきではない
  • 〇〇Managerの様な神クラスを産まない。

Open/closed principle:解放閉鎖の原則

ソフトウェアのエンティティは拡張に対して開かれていなければならないが、変更に対しては閉じていなければならない

言い換えると、「既存コードへの修正は((最小限しか)必要なく、機能拡張できるべき」だと思う。

これを実現するには、機能拡張を新しい型で追加していくのが例としてよく挙げられている。なので拡張が想定される箇所をポリモーフィックな呼び出しにしておく必要がある。

Liskov substitution principle:リスコフの置換原則

派生型(子クラス)は基本型(親クラス)と代用可能でなければならない。

子クラスは親クラスと同じ動作をしなくてはならないということ。 すごく簡単に言うなら、I/F(引数、戻り値)の型が一致していれば良い。

Interface segregation principle:インターフェース分離の原則

利用者にとって不要なメソッドへの依存を強制してはなならない。

Dependency inversion principle:依存性逆転の原則

具体ではなく、抽象に依存しなければならない。

変更されやすい実装には依存させず、安定した抽象に依存させる。 具体的にはポリモーフィックな実装にし、その際に実装クラスではなくインターフェースに依存させること。