See the Elephant

1992生まれのプログラマが書くエンジニアブログ

技術広報になって昇格した。

とても久しぶりのエントリ。ロールチェンジしたのでログを残す。

広報は「自分発の言葉」を公に扱うことがさほど多くないため、自分の言葉はここに書いていこうかなと思っている。

あってることをやってたら昇格した。

技術広報になった。技術広報とは、名の通り「技術x広報」である。

IT技術の言葉を話しながら、広報活動を行う。

技術広報になって半年で昇格した。 異動半年で昇格は珍しいそうだけど、「これまで積んできたものとその再現性」を評価してもらえたそう。

半分遊び、半分仕事

実際的に頑張ってきたのもあるが、そもそも向いていることをやっている感覚がある。

昇格自体は、ずっと望んでいたし、とても嬉しいものであった。 そして「そっちの方向で合ってるよ」と認めてもらえた感覚もあった。 というのも、20代は様々なことを試させてもらったからだ。

20代は業種も業界もピポットしながら歩んできた

一方で、最初の半年は「半分遊び」のような感覚でやっていた。 というのも、実際に趣味や副業でやっていたことを、本業の場で試させてもらっている感覚だったからだ。

振り返ると何屋だったのか謎めいている

とはいえ、数字や目標達成ももちろん大事なので、それを達成する過程における遊びである。

そのような遊びこそが、「すべてに楽しさを」を実現するための基礎のようなものだろうなと思う。

リーダーのような立ち位置なのでふざけてる場合じゃなくなってきた

今は制作の実質的なリーダーのような立ち位置になりつつある。

サーヴァントなリーダーになりたいね。

遊び心は忘れずに。

余談

このブログは、仕事で思ったことを書く方向にしよう。
See the elephantは「経験を積む」という意味だし、妥当そう。

noteは発見や取り組みを書く方にしようかな。

note.com

ドラッカーと論語 仁とはフィードバックから学び続ける人

ドラッカーと論語 を読む。

今日は第一章。

論語は紀元前500年に生きた孔子が唱えた対人関係に関する古典。

ドラッカーのマネジメントは20世紀に生きた卓越した組織論の傑作。

この2つを掛け合わせながらドラッカーのマネジメントを説明していく本書。

今日は第一章の仁に関してメモ。

仁とは フィードバックから学び続ける 姿勢を指す。

君子、つまり学識と人格に優れた人物は フィードバックから学び続ける 姿勢 を持ち続け学習回路が開いた状態の人を指す。

人の上に立つものは君子であるべきだし、君子たらざる者を人の上に立たせるべきではない、

と説く。

小人、つまり学識と人格に優れない人物は言い繕いをする。つまり仁を持たない(フィードバックから学ばない)。

故に、フィードバックから学び続ける(仁の)意思を持つことが君子を君子たらしめるのだそう。

以上

クリーンアーキテクチャ REP, CCP, CRPを学ぶとSOLIDがアーキテクチャに対しても有効なことがわかる。

クリーンアーキテクチャ REP, CCP, CRPを学ぶとSOLIDがアーキテクチャに対しても有効なことがわかる。

クリーンアーキテクチャ第13章を読んでいる。

REP, CCP, CRPについて学んだのでメモ。

SOLIDの教えがそのままアーキテクチャに適用できると知り、記事にまとめる。

SOLIDの内、 SRP, ISPに非常によく似た原則が登場する

原文に近い表現はこちら

TL;DR

凝集性(CCP: 似たものは集め、別のものは離す)について

 - REP: 同じ変更理由のものは同じリリースで変更されるようなコンポーネントの切り方に(変更理由は1つだけ:SRP)
 - CRP: コンポーネントは切り離せない単位に限定する(不要な物に依存しない: ISP)

コンポーネント

以下、コンポーネントはデプロイの単位 だと思って欲しい。

クラスやモジュールをまとめたものである。

REP, CCP, CRP

これらはコンポーネントの分割や責務の切り分けに関する原則である。

凝集性について述べる以外はSOLIDの内、 SRP, ISPに非常によく似た原則である。

凝集性

コンポーネントの凝集性について語られている。

凝集性とは以下のような性質のことである。

似たものは集まり、別のものは離れる

再利用・リリース等価の原則(REP:The Reuse/Release Equivalence Principle)

コンポーネントのリリースに関する規則。

同じ変更理由によって変更されるクラスやモジュールは同じリリースにまとめられるべき。

つまり 変更対象のクラスやモジュールが同じコンポーネント、グループに属しているべき と説く。

閉鎖性共通の原則(CCP:The Common Closure Principle)

つまりは凝集性のこと。

冒頭で説明した凝集性 似たものは集め、別のものは離す を示している。

CCPでは、 同じ変更理由で変更されるクラスやモジュールは同じコンポーネントにあるべき と説く。

コンポーネント版、SOLIDのSRP。

単一責任の原則(SRP: Single Responsibility Principle)クラスの変更理由は1つ(同じアクター<ユーザやプレースホルダー>) であるべき と説く。

全再利用の原則(CRP:The Common Reuse Principle)

ひとつのコンポーネントにまとめるクラスはどれも切り離せないものばかりにする(不要なものに依存しない)。

コンポーネント版、SOLIDのISP

インタフェース分離の原則 (ISP: Interface Segregation Principle)使っていないメソッドを持つクラス(インタフェース)に依存しない(不要な物に依存しない) と説く。

REP, CCP, CRPを学ぶとSOLIDがアーキテクチャに対しても有効なことがわかる

凝集性(CCP: 似たものは集め、別のものは離す)について

 - REP: 同じ変更理由のものは同じリリースで変更されるようなコンポーネントの切り方に(変更理由は1つだけ:SRP)
 - CRP: コンポーネントは切り離せない単位に限定する(不要な物に依存しない: ISP)

凝集性についてSOLIDのSRP(CCP), ISP(CRP)を適用するとコンポーネント分割や責務の切り分けに有効であることがわかった。

SOLIDを理解すると2度美味しい。

以上

テスト駆動開発(TDD)はもう終わっているのか? Part1を読んでリポジトリ層に関するMockについて思いをはせる

postd.cc

TDDとモックの話

  • Mockによって中間地点のゴールを作ることができるメリットがある

  • Mockを多用しすぎることでリファクタリングが難しくなる場合もある

mock多用のチームからmock使わないチームに異動したけど、個人的にはない方が楽やなと思う

過去の和田さん(t-wada)とのペアプロ

「現実を模したMockを作り実装を合わせるべきで、実装に合わせたmockを作るべきでない 」

と言われたことを覚えている

実装のあとにテストを行うと実装に引きずられたテストケースとMockを書きがち

これを追認のテストと呼ぶそう。

Mockが便利すぎた結果、実装を"許す"形でテストを書かないように気をつけなければいけない、とおっしゃってた

Mockがないと、現実の制約の中で戦わざるをえないのでそっちのほうが結果的に楽だなと思う

友人がt-wadaさんのツイートを教えてくれたので雑談

DBドライバのMockを"自作自演"と呼ぶのはとても腑に落ちて素晴らしい表現だと思う。

友人曰く、

なんでもかんでもモックするのはどうなんだろう? という同じ疑問を持っていた

だそう。

自分的に以下のように考えている。

DB ドライバをモックにするとひたすら自作自演を行うテストになってしまうので、私は実際にデータベースとやりとりを行うテストを書きます。

あーもうほんとうにこれです。

前のプロジェクトはrepositoryをmockしてたけど、DBが返却しない値を設定できてしまうのでそれはあまり勧められた設計ではないなと思った

自分の開発マシンに入るものは常に本物を使い、入らないものだけモック/スタブを使います

めっちゃなるほどだ。。。

(友人) 今だとDocker とかで本番に近い環境整えることができるからなおさら本物を使ったほうがいいのかなーと思う

(自分) 今のチームだと実際にDB書き/読みにいくところまでテストされてますね

DBの制約とかDTOビジネスロジックのテストとしてはそっちの方が明らかに利点あるなーと思います

友人の言う通り、今ならdockerでチームメイトに同じDB seedや環境を配ることができる。

そう思うとDBに対してはMockingせず、本物を使う方がいいのだろう。

mysql server(mysqld)の起動をn回リトライして待つshellコマンドとmakefileを書いた

この記事の対象読者

  • mysql serverの起動を待つスクリプトが欲しい
  • docker-compose で mysqlを使っているが上手く初期化できない

    • なぜか初期化処理がbuildプロセスだけ失敗する
  • 以下のエラーでググってhostを直しても一向に直らない

ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0

TL;DR

mysql server(mysqld) の起動を待つ処理を入れましょう。
通常であればこれでいいと思います

$ mysqladmin --wait --count 3 ping || exit 1

docker-composeだとちょっと癖があるので上記以外で対処します。

shellはこんな感じ

for i in 1 2 3 4 5; do mysqladmin ping &>/dev/null && break || sleep 1  && [ 5 -eq $i ] && exit 1; done

人によってはこっちでもいいかも: 処理が成功するまで実行しつづける@katzchang

mysql server(mysqld)の起動を待つshellコマンドとmakefileを書いた

mysql server(mysqld)で起動直後にサーバ接続ができないケースがあった。

困ったので接続できるまでn回リトライし続けるshellコマンドと makefileを書いた。

無限に待ちたいわけではない ので今回は n回 と言う制約を持たせる。

僕はdocker-composeを使っているのでそれ前提で話をすすめる。

同じく困ってる人はいるんじゃないかな、と思ったのでメモる。

docker-compose で mysqlコンテナへ起動直後に接続できない!

今回は docker-composemysqlのコンテナを立てるケースを考える。

コンテナのbuild直後にmysqlに接続できないことがあった。

これでは、buildしたあとにエラーが起きDBの初期化処理が続けてできない。

マイグレーションもできないし、設定もできなくて困る。

コンテナ起動直後はmysql server(mysqld)が立ち上がっていない。

docker container が立ち上がった直後は mysql server(mysqld) がまだ起動していない。

mysql client(mysqladmin) から接続を試みるとこのエラーが出る。

ERROR 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 0

エラーメッセージでぐぐるとhostの設定が足りないとの記事が出てきてめちゃめちゃハマった。

そうじゃない。

sleep n秒が1番簡単な解決方法

マイグレーションなどの処理の前に sleep 60 する

mysql server のデーモン起動(mysqld)まで待てばいいのでこれでok。

起動までリトライしたい

60秒を超えてmysql serverが起動した場合、 sleep 60 だと対応できない。 時間 or n回 リトライするような作りになっていればよい。

How do I write a retry logic in script to keep retrying to run it upto 5 times? より拝借

for i in 1 2 3 4 5; do command && break || sleep 1; done

これを使えば 5回, 1秒ごとに 成功するまでcmdを繰り返す 状態を作り出せる。

mysql serverのlifecheckは mysqladmin ping で行える。

for i in 1 2 3 4 5; do mysqladmin ping && break || sleep 1 ; done

これだと mysql serverが起動してようとしてなろうと次の処理へ行ってしまう。

そこで最終ループのときに exit 1 で抜けるようにした

for i in 1 2 3 4 5; do mysqladmin ping && break || sleep 1 && [ 5 -eq $i ] && exit 1; ; done

makefile で rangeを指定する

build中のタスクランナーとしてmakefileを使っている。

n回処理する記述は以下のように書ける。

RETRY_COUNT=30
RETRY_RANGE=$(shell seq 1 $(RETRY_COUNT) | xargs)

mysql/lifecheck: 
  for i in $(RETRY_RANGE); do mysqladmin ping &>/dev/null && break || echo '.' && sleep 1  && [ $(RETRY_COUNT) -eq $$i ] && exit 1; done

mysql/wait:
  which mysqladmin
   @echo "waiting boot mysql..."
  $(MAKE) mysql/lifecheck

dockerでmysqlコンテナを立てる時の設定 my.cnf

dockerでmysqlコンテナを立てる時の設定 my.cnf

mysqlのconf について学ぶ。

ざっと出すとこんな感じ

[mysqld]
skip-host-cache
skip-name-resolve
character-set-server=utf8mb4

[client]
default-character-set=utf8mb4

mysql server, clientの設定がそれぞれ書いてある。

server 設定 mysqld

skip-host-cache

www.na3.jp

MySQL :: MySQL 5.6 リファレンスマニュアル :: 8.11.5.2 DNS ルックアップの最適化とホストキャッシュ

これはDNSのキャッシュ戦略機能をオフにする宣言。

ipアドレスから引かれたホスト名がすでにキャッシュされている時にそれを使い回す機能があるそう。

docker-composeでコンテナを立てる場合、docker networkがよしなにprivate ipを当ててくれるからわざわざdnsで名前解決しなくていい。

skip-name-resolve

gihyo.jp

MySQL :: MySQL 5.6 リファレンスマニュアル :: 8.11.5.2 DNS ルックアップの最適化とホストキャッシュ

これも同様にDNSの名前引きを飛ばす設定。

character-set-server=utf8mb4

mb4 がポイント。

mysqlのutf8は1-3byte文字しか扱えない。

iOS, Androidの絵文字, 最近追加された難しい日本語や中国語は4byteあるためこれらの文字列を格納しようとするとエラーが起きる。

そこで utf8mb4を使う。

flhouse.co.jp

clientも同じ

クリーンアーキテクチャから学ぶSOLID : SRP

クリーンアーキテクチャから学ぶSOLID : SRP

クリーンアーキテクチャを読んでいる。

Clean Architecture 達人に学ぶソフトウェアの構造と設計

TL;DR : モジュールはたったひとつのアクターに対して責務を負うべきである が結論。

SRP: 単一責任の原則

要約すると アクターごとにモジュールを分けましょう。そうすると変更影響がアクター単位に閉じるから。 と言っている。

SRPはSingle Responsibility Principleの略で単一責任の原則と呼ばれる。

原著ではこう書かれている。

モジュールを変更する理由はたったひとつであるべきである

と書いてあるのだけど これが分かりにくい。

Unix哲学の 一つのことを上手くやる と混同しやすい表現になっている。

モジュールを変更する理由はたったひとつであるべきである = ひとつのことをうまくやる?

UNIXという考え方―その設計思想と哲学 によると

ひとつのことをうまくやるようにプログラムを作れないのであればおそらく問題をまだ完全には理解していないのだろう

自分は名前からはこう解釈した。

コードベースの変更理由が1つでない => 機能に持たせる役割が1つでない => 問題の切り分けが不完全 と誤解してしまう。

少なくともでもそうではないのだ。

SRPとは アクターごとにモジュールを分ける 提案をしている

SRPは 機能を小さくするべき ではなく、アクター(ユーザやプレースホルダー)ごとに機能を切り分けるべき と言っている。

クリーンアーキテクチャ では Facadeパターンを使って説明している。 TechScore Facadeパターン

Facadeパターンは機能の入り口となるクラスが他のクラスを利用することで機能を提供する。

他のクラスを使い方を知っており、一連の機能を提供するManager, Serviceクラスとその従属クラスのようなものを想像すればいい。

共通で使うクラスでアクターごとに違う振る舞いを他のクラスに移譲する

たとえ話をしよう。

3つの異なる役職のアクターがいるとする(例えばCTO, CFO, COO)。

こららアクターが共通で使うEmployeeクラスがある。

Employee には calculatePay 関数があり CFO, COOが利用している。

calculatePay をCOOの都合で書き換えた時、COOにも影響を与える。

CFOは知らないうちに数万ドルの損失を出すかもしれない。

複数のアクターで全く同じクラスを使うと、変更の影響が伝搬する。

<facadeを使うと…?>

このとき CFO, COOごとに (CfoCalculatePayのように) 機能を別のクラスに移譲する。

Employeeはアクターに適した振る舞いを持つ個々のクラスを呼び出す形にする。

そうすることで CFO都合の変更は CfoCalculatePay に閉じるし、 COO都合の変更は CooCalculatePayに閉じる。

モジュールを変更する理由はたったひとつであるべきである は主語が抜けていて誤解しやすい。 実際には モジュールはたったひとつのアクターに対して責務を負うべきである

クリーンアーキテクチャ では SRPをこのように解説している。

コンウェイの法則から導かれる当然の帰結。個々のモジュールを変更する理由がたったひとつだけになるように、ソフトウェアシステムの構造がそれを使う組織の社会的構造に大きな影響を受けるようにする

『Clean Architecture』における単一責任の原則とコンウェイの法則について

コンウェイの法則

システムを設計する組織は、組織のコミュニケーション構造をコピーした構造の設計を生み出す。

つまり、組織の構造をそのままアプリケーションの構造に取り入れましょう、と言う話なのだろう。

SRPについてそこそこ深く理解できた気がする。