patorashのブログ

方向性はまだない

スキーマ駆動開発は依存関係逆転の原則を適用したものだと気づいた

ここ最近、チーム内で設計力強化のためにクリーンアーキテクチャ読書会をしているのだけれど、そこで気づいたことがあるのでメモとして残しておく。

18章の境界の解剖学を読んでいた際に、クライアントとサービスの図があったのだが、下位レベルのクライアントから上位レベルのサービスへの呼び出しとなっていた。しかし、ここでサービスのインターフェースを挟むことで、上位レベルのクライアントから下位レベルのサービスへの流れとなっていた。

このサービスのインターフェースこそが、Swagger Editor等で作るWebAPIのスキーマであり、バックエンドはこのスキーマをインターフェースとして捉えてこれをimplementする形で実装する。フロントエンドは、WebAPIのスキーマをインターフェースとして呼び出すことを前提として作れば、フロントエンドとバックエンドは疎結合となる。

スキーマ駆動開発はフロントエンドとバックエンドを疎結合にして実装できる、とは以前から認識していたのだけれど、依存関係逆転の原則を適用したものだとは本を読むまで気づいてなかったので、気づいたときはすごく嬉しかったというか、ワクワクした。

一回読んだだけだと全然よくわかってなかったんだけれど、色々見えるようになってきてから読むと、また気づきがあるなと思えた。

2022年9月に取り組んだこと

とりあえず、前回の記事からほぼ1ヶ月くらい経過しました。前回の記事では、昇進して課長になったよという話を書きました。

patorash.hatenablog.com

この1ヶ月で取り組んだことをざっと書いていこうかなと思います。

  1. 独自にOKRの導入
  2. スプリントのふりかえりのフォーマットを変更した
  3. 1on1の資料のフォーマットを変更した
  4. 朝会・夕会のフォーマットを変更した
  5. Yammerで日報を開始した
  6. 開発チームのメンバーに求めるものを定義した
  7. 曜日毎に取り組む作業を変更するルールを定義した
  8. レビューはモブレビューするようにルールを定義した
  9. PRのマージはPRを行った人が行うようルールを定義した
  10. コードのメソッドにドキュメントを書くようルールを定義した
  11. gitのコミットにプレフィックスをつけるようルールを定義した
  12. 読書会の主催を前チームの後輩氏に引き継いだ
  13. クリーンアーキテクチャ読書会をチームの一部のメンバーで始めた
  14. 個人の目標の確認をしやすいようにMS Listsで公開した
  15. AWSの勉強に取り組みやすいように情報を整理し、MS Listsで公開した。進捗も確認できるようにした
  16. New Relicの勉強会に参加。その後、遅い処理の見つけ方、RedMineへの報告の仕方を指示した
  17. 某システムの設計の開始。設計に入る前に改めて全体像の把握や疑問点の洗い出しなどを行った
  18. 自分のPCに現行システムの開発環境のセットアップを行った
  19. 管理職になったので、管理職会議や週次報告、お金に関わるところの確認・承認などなど
  20. 前チームで作っていた製品のコードレビューや、相談にのったり等。

うーん、結構やった感あるな…。

この中から、今回はコミュニケーションに関わるところの変更について書いていこうと思います。

フォーマット変更系

スプリントのふりかえり

最初はとりあえず見てみようかなと思って、観察していたのですが、もともとのスプリントのふりかえりのフォーマットが

  • 良かったこと
  • 悪かったこと

になっていました。悪かったことはなんか言い出しにくそうだし、良かったことは「別にないなぁ…」となりがち。

そこで、以下の記事を参考にして変更しました。

ihcomega.hatenadiary.com

  • 聞いてほしいこと
  • お礼したいこと
  • 自慢したいこと
  • 続けたいこと
  • 変えたい・なんとかしたいこと

順番はこのようにしています。これは、気分一致効果を狙ったもので、ポジティブな気持ちになってから、変えたい・なんとかしたいことに向き合ってほしいからです。

また、ふりかえりのレジュメは数日前から公開しておき、事前に記入してもらうようにしました。当日に聞くと、よく喋る人しか言わないので、じっくり考えたい人もいるのでそうしています。このフォーマットに変えてからまだ2回しか行えていませんが、以前に比べたらお礼や自慢したいことでコミュニケーションが取れたり、問題提起に関しても多く出てくるようになったかと思います。

また、今回のスプリントどうだった?というよりは、OKRの達成度に変化あったか?という視点でふりかえりを行い、次のスプリントゴールを定義するときに、OKRの達成度を上げるための取り組みを意識するようにできたかなと思います。

1on1の資料のフォーマットを変更した

こちらも、部門目標・個人目標を意識したフォーマットに変えました。といっても、ほとんど、とある本の丸パクリです。

  • 前回のスプリントでよかったことを3つ以上あげる
  • 次のスプリントで、こうできたら最高だなと思うことを3つ以上あげる
  • 前回のスプリントでの反省点を3つあげる
  • ネクストアクションと、そのネクストアクションの始めの一歩を考える

「重要だけれど緊急ではないこと」が個人目標に設定されていることが殆どなので、それを意識して取り組んでもらえるようにしました。私はこの本の中に出てきた「仮決め・仮行動」という考え方がすごく気に入りまして、「とりあえずこう仮決めしといて、とりあえず取り組んでみようや」というノリのおかげで重要だけれど緊急ではないことにサクッと取り組めるんじゃないかなと考えたので、丸パクリしているところです。もちろん、このフォーマットも仮決めです!しっくりこなければやめます。

あとさっき書いた気分一致効果もこの本で紹介されていたものになります。まず悪かったことから…とならないように振り返ることの大事さが書かれていてよかったです。

ネクストアクションを書いてもらい、さらにそのネクストアクションを行うための始めの一歩を書くようにしてもらってます。始めの一歩が次の行動を自然と起こすキッカケになるので、これもこの本を参考にしました。

朝会・夕会のフォーマットを変更した

朝会・夕会はデイリースクラムなので、目的は何をやってたかの報告ではなく、「スプリントゴールへの道を阻害するものを早く検出すること」なので、そういう視点で書いてもらうようにお願いしています。お願いしていますが、今の所そこまで出てきてません…。まぁ時々出てきているので、問題はないかなと思いつつ…。

Yammerで日報の運用を開始した

日報は、前も行われていたのですが、夕会の作業報告用であり、Teamsで行われていました。 しかし、これではその日の夕会でしか使えないので勿体ないと感じていました。

そこで、Yammerに日報コミュニティを作り、そこに個人を示すハッシュタグ付きで投稿してもらうようにしました(ちなみにTeamsはハッシュタグ使えません!)ハッシュタグ #名字日報 をつけることでハッシュタグをクリックしたらその人の日報だけに絞り込まれるようにしてあります。

これで、私は週次報告する際に個人ごとの活動を確認するのに便利だし、各メンバーは1on1等で、このスプリントで取り組んできたことをふりかえるのに便利、というわけです。

そして、フォーマットをYWTを改良したYWTKにしています。

  • Y: やったこと
  • W: わかったこと
  • T: 次にやること
  • K: 気になること

気になることは、なにかしら新しい情報や、面白そうな話題等について自由に書いてもらってます。障害があったときには、Aは対応したが、Bのほうは大丈夫だろうか?とかも。

朝会が始まる前に、Teamsで「前日の日報を確認してリアクションお願いします」と自動で流すようにしています。気になること・わかったことを共有してもらえるので、他の人の参考にもなったり、やったことの中で躓いた点などがあれば他のメンバーから「こうしたらいいんじゃないか?」とコメントがついたり、いいねなどのリアクションが付いたりしますし、実際の朝会の際に日報で書いていた件を話題に上げたり等、以前より確実にコミュニケーションが活発になったと思います👍

まとめ

という感じで、コミュニケーション設計でやりたかったことは1ヶ月でザーッとやることができたかなと思ってます。一気に色々と変えたので、大丈夫かな?と心配なところはあったのですが、「意図が伝わったしどれも大事だなと思ったので特に嫌だなと思ったりとかはない」、「どこに書けばいいかわからなかったのでまぁいいやと思って何もしてなかったことがあったが、ここに書けばいいのか、と書くところができたのはよかった」などのポジティブフィードバックを貰えたので、今の所よかったかなと思います。

運用を続けて、メンバーの成長と会社への貢献がガッチリ組み合わさっていけたらいいなぁと思います。

オマケ

うちのチームでメンバー募集しておりますので、RubyRailsアプリの開発・運用・保守や、AWSでの運用・保守に興味のある方はのほうまでご連絡いただけると助かります🙏 運用・保守の関係で、できれば岡山の方が望ましいですが、基本開発メンバーはリモートなので、岡山県外の方でも募集中です。

株式会社 リゾーム | システム開発(保守運用担当):岡山本社勤務 | IT/Web業界の求人・中途採用情報に強い転職サイトGreen(グリーン)

株式会社 リゾーム | システム開発(開発者):基本リモート勤務 | IT/Web業界の求人・中途採用情報に強い転職サイトGreen(グリーン)

開発だけでなく、システム管理系も募集しています。こちらもよろしくお願いします🙏

株式会社 リゾーム | システム管理(社内SE・情報システム)(岡山) | IT/Web業界の求人・中途採用情報に強い転職サイトGreen(グリーン)

株式会社リゾームで昇進しました(2回目)

うちの会社は期首が9月で、今期で昇進した。世間では退職エントリーとか入社エントリーが多いから、自分は昇進エントリーを書く。(2回目)

なお、1回目はこちら。3年前ですね。

patorash.hatenablog.com

課長に昇進した

うちの会社ではキャリアとしてマネジメント職と専門職がある。前期までは専門職だったが、今期からはマネジメント職になる。マネジメント職になった経緯は、まぁ正直なところ横滑り的な感じではある。昨年、このポジションにいたカズさんこと id:tech-kazuhisa が退職したことで、傍から見ていた感じではあるが、チームが一気に硬直化してしまったように思えた。カズさんの存在の大きさがよくわかった1年だと感じた。

まぁそんなこんなで日々の雑談タイムや読書会などで彼らの話を聞いていると、色んな不安や不満の話が出てきたりするのだけれど、当時の自分は、違うチームのリーダーだったし、かといってこのままだとマズイなぁというのはヒシヒシと感じていた。 「こうなったら、私が課長やるかー」という気持ちになってきたので、打診したところ、じゃあ来期から課長で!ということになったのだった。

マネジメント職の職責

マネジメント職の職責としては、

  • 組織の上位方針に沿って部門目標を立てる
  • 部門目標を達成するための計画を立てる
  • 計画を遂行するための指揮を取る
  • 部門メンバーの様々なサポートを行う
  • 他部門との調整を行う
  • お金の関わる辺りのやりくり

あたりだろうか?当たり前だけれど、専門職とは求められるものは随分異なる。今までよりも、より成果を求められるので、チームをいかに強くしていくかにかかっていると思う。

課長になってやっていくこと

さきほど、チームをいかに強くしていくかにかかっていると書いたばかりだが、今期はそこはそこまで重要なポイントとは思っていない。 まずは差し当たっての不満・不安を解消していくことだと考えている。その要は部門目標である。

部門目標・個人目標を明確に

期が変わる1ヶ月前に、今期の体制が発表されるため、8月はまだ課長ではないものの、今期の課長として部門目標を立てたり、それを達成するための計画作成、そして部門メンバーの個々の目標作成などについてミーティングを重ねた。なにせ、雑談や読書会で一緒に話したりはしているものの、違うチームから来た人間が課長になるので、現場の感覚と一致していない目標を立てられたら白けるだろうと思ったので、自分が考えた叩き台の目標と計画を事前に説明し、現場の意見をもらいながら修正して現実的なところに落とし込んだ。しかしそれでもかなりアグレッシブな目標にしてある。

成果の定量

開発部門は目標をなかなか定量化しづらいのだが、達成基準として、

  • 期日を設定し、前倒しで開発できたら評価に加点
  • ○名が運用・保守に参加できる技能を習得する
  • 既存システムの改善ポイントを見つける毎に評価に加点

など、加点ポイントを多く盛り込んだ。 開発だと、大概のことが「業務なのだから、やって当たり前」とされてしまい、せっかく改善ポイントを見つけても、やるのは発見した本人になるし、やったところで当たり前だから評価のポイントにはならない。だったら見つけてもあまりやりたくない、という負のスパイラルを生みがち。 その人の職位にもよるけれど、そのあたりは評価されて然るべきと思ったので、まずはそのスパイラルを断ち切りたい。

定量化されていれば、それ以上の成果を出せた場合はアピールしやすいし、途中経過が芳しくなければ、ふりかえりで対策を練ることができる。加点を狙って動けるようにするのが目的。一見、評価気にしすぎじゃない?と思われるかもしれないけれど、評価の高くなる成果は組織にとって良いことなのである。しょうもないことを評価するようにしているわけではない。

コミュニケーション設計

コミュニケーションはコロナ禍になってから更に希薄になっていると思うのだけれど、もうちょい活発になってほしいなぁと考えている。かといって、なんでもいいから雑談しろってのは無理があるので、コミュニケーション設計していくからねという話はした。

まぁ簡単に書くと日報を書こうってことと、他のメンバーの日報に、できればなにかしらリアクションしましょうってあたり。 日報には他の目的もあって、1on1の際に何をやってきたかを蓄積できるので、より振り返りしやすくなる。

あまりコミュニケーションが薄いと、チームワークが発揮されにくい。逆にいえば、コミュニケーションを増やせば自ずとチームワークが発揮されるようになるはずなので、コミュニケーションを取らないと達成できない形の目標を作ったりもした(もちろん両者同意の上で)。

管理職としての決意

部門目標を達成することは大事だけれど、やはり現場で働くメンバーが楽しくやりがいを感じて仕事できるようにすること、そして、給与面での待遇改善が、管理職としての重要な役割だと思う。体制としては上司と部下であるけれど、本質は役割の違いでしかないと思う。だから、そこを気にして発言できないようなことにはしたくない。心理的安全性のある関係を作りつつ、チームワークを発揮して成果を出して、その成果はしっかりアピールして、メンバーが昇進・昇給できるようにやっていく所存です。

頑張るぞー!

ActiveRecordでテーブルコメントを参照する

小ネタです。migrationの際にテーブルコメントを追加する情報は検索すればいくらでもヒットするんですが、ActiveRecordでテーブルコメントを参照する方法はなかなかヒットしなかったので、メモしときます。

環境情報

方法

ヒットしたのはAPI Dockのこれ。 apidock.com

ConnectionAdaptersのメソッドです。引数にテーブル名を渡します。 モデルから直で取れるメソッドはなさそうでした。

connection = ApplicationRecord::connection
connection.table_comment(:users) # usersテーブルのテーブルコメント取得

User.table_nameみたいに、User.table_commentで取れてほしいなぁ〜。

Elasticsearchへの保存を非同期ではなく同期で行う方法

環境情報

DBに保存したらElasticsearchも更新されたい

Railsプロジェクトで、データベースへの保存を行ったら同時にElasticsearchへの反映も行いたい、というケースが出てきました。

Elasticsearchの利用には、elasticsearch-railsを使っているのですが、データの反映は簡単でした。

# Elasticsearchへの保存が失敗してもロールバックしたいので…
class Foo < ApplicationRecord
  def apply!
    ApplicationRecord.transaction do
      # なんやかんかして
      self.applied = true
      self.save!
      self.__elasticsearch__.index_document # => これでElasticsearchにも反映される
    end
  end
end

画面側で確認しても問題なし👍Elasticsearchを使う検索フォームで検索してもOK。

問題発生(テストが落ちる)

しかし、RSpecでテストを書いたら、落ちる…😥

require 'rails_helper'

RSpec.describe Foo, type: :model do
  describe '#apply!' do
    subject { Foo.create!(applied: false) }
    it '反映されること' do
      expect {
        subject.apply!
      }.to change { subject.applied? }.from(false).to(true)
      definition = Elasticsearch::DSL::Search.search
      definition.query do
        must do
          term applied: true
        end
      end
      result = Foo.__elasticsearch__.search(definition).records
      expect(result).to be_present # => ❌存在しないと言われる👻
    end
  end
end

調査

なんとなく、もしかして非同期更新か?と思い、雑に2秒待つようにしたら、テストが通るように!

require 'rails_helper'

RSpec.describe Foo, type: :model do
  describe '#apply!' do
    subject { Foo.create!(applied: false) }
    it '反映されること' do
      expect {
        subject.apply!
      }.to change { subject.applied? }.from(false).to(true)
      sleep(2) # => 2秒待つ…
      definition = Elasticsearch::DSL::Search.search
      definition.query do
        must do
          term applied: true
        end
      end
      result = Foo.__elasticsearch__.search(definition).records
      expect(result).to be_present # => 🟢通った👍
    end
  end
end

とりあえずテストは通るようになったけれど、テストにsleepとか入れたくありません。どうにか同期的にデータ更新できる方法はないものか…とコードを読んでいきます。

https://github.com/elastic/elasticsearch-rails/blob/main/elasticsearch-model/lib/elasticsearch/model/indexing.rb

Yardを読むと、@param options [Hash] Optional arguments for passing to the clientと書いてあるけれど、いやそのHashにどう設定すればいいかがわからん!😠

ググったら、zennの記事がヒットしました。

zenn.dev

コードの感じからすると、Kotlinかなんかだろうか…?とりあえずrefreshオプションがあることがわかりました。

www.elastic.co

解決方法

というわけで、該当箇所を修正。

# apply!メソッドの一部
self.__elasticsearch__.index_document(refresh: true) # => Elasticsearchに同期的に反映

これで、sleepなしでもRSpecが通るようになりました👍

テストの時だけ同期をとるようにしたい

しかし、なぜ非同期でElasticsearch側に反映されるかというと、パフォーマンス向上のためですね。つまり、毎回同期をとるように更新していたら、遅くなります。ループでFoo#apply!メソッドを呼ぶこともあるので、それは避けたい…。 そもそも、普段は即時同期が取れていなければならないほどシビアな条件でもありません。単に、テストの時だけ同期が取れていればいいわけです。

そこで、該当箇所を以下のように修正。

# apply!メソッドの一部
self.__elasticsearch__.index_document(refresh: Rails.env.test?) # => テストの時だけElasticsearchに同期的に反映

これで、テストの時だけElasticsearchへの反映が同期的になりました👏👏👏

「現場で役立つシステム設計の原則」読書会 vol.10

第10回の感想です。前回の感想はこちら。

patorash.hatenablog.com

会社のブログのレポートはこちら。

tech.rhizome-e.com

最後なのでみんな参加できるようにしようということで日程調整してから行ったので少しずれ込みました。というても5月前半だったので、私がブログ書くのが遅かっただけですね、はい。色々バタバタしてまして。もう次の読書会が始まってますし(汗)

10章 オブジェクト指向設計の学び方と教え方

  • オブジェクト指向の説明は意味不明というところ…。まぁそこまで意味不明とは思っていなかったんだけれど、ドメインオブジェクトを設計していくという考え方にはあまりなっていなかった…というか値オブジェクトを作っていくというところがあんまりなかった。受託開発の場合、リファクタリングをする機会などほぼ与えられないため、嬉しさはよくわかっていなかった。
  • オブジェクト思考の学び方、リファクタリグ。こっちのほうがいいと思う。
  • 極端なコーディング規則を作ると、1人ならいいのかもしれないけれど、チームでやるとイライラしそう。
  • 本の紹介があった。リファクタリング Rubyエディションは会社に置いてあるはず…。ただ、情報が古いので現在だと微妙かも。過去に有志で読書会やったけれど(当時の参加者は自分以外は転職してるが)、なんでやねんってよく言ってた。しかし今見返すと「なるほど」となるかもしれない…。
  • オブジェクト指向の考え方を理解する。のところ。この本に書かれていることで十分な気もするんだけれど。エヴァンスのドメイン駆動設計はよく紹介されている。Kindle積読してある…。書かれたのが2000年代初頭なので、それを念頭において読まなければならないと、texta.fmでt-wadaさんが言ってた。本に書いてある通りの実装方法が現代においては冗長だったりするらしい。難しい本なので、この本こそ、読書会で取り組んだほうがいいかもしれないと思った。

私はPodcastGoogle podcastで聴いてるので、リンク貼っておきます。

podcasts.google.com

雑感

エリック・エヴァンスのドメイン駆動設計は他の先輩社員にもオススメされていたという話が他チームの参加者からあった。まだちゃんと読んだことないので、いつか読んでみたいとは思っている。これも読書会とかでやらないと多分読み切れない気がする…。 どうやってオブジェクト指向を学ぶか?というテーマでは、「やっぱりリファクタリングしながらうまく構造化できたりして身についていくもんじゃないですかねー?」という感じだった。 とあるメンバーが、「実際に動いている業務コードがあるのだから、それを触れていくのが一番手っ取り早い。なので整地日(リファクタリングデー)を活用してやっていけたらいいと思うんですけど、整地日にみんなが取り組むのがドキュメントの整備とかが多くて、コードの整地がほとんど進んでない」と話してたと思う。まぁドキュメントの整備も重要なので、いいとは思うんだけれど、ずっとドキュメントの整備をしてたら進まないというか、ドキュメントの整備は整地日じゃなくて普通の業務の日に取り組むべきじゃないか?と思った。まぁそれはそう伝えたような…(ちょっと前なので記憶が曖昧)

この本を読んでる最中にリファクタリングしましたか?という質問には、あまりいい返事がなかったので、やや悲しい。私は得られたことがかなりあって、ガシガシとリファクタリングしていってたので、みんなも取り組んでるかなと思ってたので、返答が意外だった。しかし、後日、同じチームの後輩氏と一緒に取り組んだリファクタリングデーでは、後輩氏のコードはちゃんと本の内容を意識したコードになってるなと思った。あとやっぱりコードレビューのときの指摘の説明が簡単で済むのが助かる。開発もまた、ドメイン知識の共有なのだと思う。

読んですぐ手を動かす瞬発力を身につけさせるにはどうしたらいいのだろうか?

読書会全体を通して

今回から、事前に読んできてもらって、感想や疑問・他の人の感想に対する疑問・アドバイス、そこから派生して業務の雑談(自然とテーマは本の内容に近くなる)などを1時間~1時間半くらいでやってました。そして、テックブログも始まったので、せっかくだからこういうことやってるよとテックブログで発信していこうと話して、交代しながらアウトプットもしました。

なんとなく感じているモヤモヤを相談する場にもなっていたので、やった甲斐はあったかなと思います。解釈の違いに気づけたりもしました。それはやっぱり1人で読んでいるとわからない点ですね。

twitterでは、テックブログの記事について、者の @masuda220 さんにRTしていただいたりしたので、そのときはアクセスが増えてました👍ありがとうございます。

オブジェクト指向言語でどう開発していけばいいかを網羅した素晴らしい書籍だと思います。新人教育など、ある程度経ってから、また読書会を開いていけたらいいなと思いました。

Herokuへのデプロイが成功しているのにgitのエラーが発生する件に対応した

git pushでHerokuにデプロイしたら、デプロイは成功しているのに、最後にエラーメッセージが出てしまう現象に遭遇しました。

$ git push heroku release-yyyymmdd:master
# なんやかんやあって

remote: Waiting for release.... done.
fatal: protocol error: bad line length character: fata
error: error in sideband demultiplexer
error: failed to push some refs to 'https://git.heroku.com/xxxxxxxxxx.git'

いや、release..... done.ってなってるやないか。なんで最後エラーに…。このせいでデプロイの自動処理がここで止まってしまう…。

fatal: protocol error: bad line length characterググると、.bashrcでechoしてないか?とか、色々出てくるんですが、確認したところ、そういうこともしていませんでした。

エラーメッセージと、herokuで検索したら、それっぽいのをstackoverflowで発見!

stackoverflow.com

これのコメントにある通りに対応したら、直りました👍

$ heroku plugins:install heroku-repo
$ heroku repo:reset -a xxxxxxxxxx
$ git commit --allow-empty -m "Reset repo"
$ git push heroku release-yyyymmdd:master

Herokuのリポジトリをリセットしたら直ったってことは、なんか壊れていたってことなんかなぁ〜🤔と思いつつ、これで終わりとしたいと思います。