島までは遠い 〜サークルアラウンド株式会社代表佐藤のブログ〜

佐藤正志@サークルアラウンド株式会社のことが少しわかる場所。プログラマーを育てるトレーナーとして、現役のソフトウェア技術者として、経営者の端くれとして、想うことをつづる。

ボヤッとした目標を達成可能なところに落としこむ手法

f:id:ms2sato:20200103232723j:plain

はじめに

新年なので新しく目標を立てようと考えている方、多いのでは無いでしょうか。ただ、漠然と宣言するだけだとなかなか達成が難しいと思います。せっかくなので、目標の具体化とか達成しやすい整理などを一緒に考えられると良いな、という感じのエントリーです。

ちなみに「昨年本を20冊読んだから、今年は30冊読む」のような定量的な目標を量を増やしながら達成している方よりも「そもそも何すると良いんかな」と迷ってしまう人向けです。

ぼやっとしている内容から「よしこれをやるぞ!」までのブレークダウンのようなエントリーです。

達成したい大まかな方針を決める(ぼやっとした希望)

おそらく様々な目標はあれど、単なる欲望の発露でない限りは「理想と現実のギャップ」がそこに存在していると思います。つまり「問題があって、解決したい」というようなことが多いのではないでしょうか。例えばよくあるようなことだと以下のようなものですかね?

  • シェイプアップする(体が弛んでいる)
  • 恋人を作る(恋人がいない)
  • 仕事で活躍できるようになる(今活躍できていない)

ちなみに「シェイプアップしたい理由が、恋人を作りたいから魅力的な自分になりたい」みたいなこともあると思うので、その場合には頭の中で最終目標としてのイメージはあると良いと思います。とは言えあまり考え過ぎるとと進まないと思うので、そこそこぼんやりでも大丈夫です。必要なのはあくまでも方針(どのような方向に自分を高めたいか)でしょう。

大まかな方針を要素に分解する

例えば「仕事で活躍できるようになる」と方針を決めたとして、仕事で活躍できるにはいくつもの要素があるとわかります。仮にプログラマーであれば以下のような感じに進めていけるかもしれません。

こういうことするのに マインドマップを使う人は多そうですね。ツールを利用する方がやりやすい場合にはそういうものを使うのも手です。まぁ、単なるまとめかたの問題でもあるので、箇条書きをインデントしていくだけでも十分だったりします。

「何か綺麗にまとめないといけないのではないか」という心理に駆られてしまうタイプの人は一旦そういうことを置いといて「出してみること自体に価値がある」と考えてくれると良いのではと思います。まずはドバーッと出してしまって、あとで整理すれば良いでしょう。大切なのは出力された内容そのものであって、整理されているかどうかはその次です。

  • コードを書くのが遅い
  • コードにバグが多い
  • レビューで突き返しが多い
  • 仕様の理解不足で間違ったものを作ってしまった
  • 「なぜ早く相談しなかった?」といつも言われている
  • もっと大きな機能を実現できるようになれないといけない
  • 人の話からどういう機能が必要か提案できるようになりたい
  • 相手が理解しやすいように説明することができない
  • 同じ失敗を何度も繰り返してしまう
  • 関数の名前がいつも適切にできない

もしかしたらネガティブなことが出まくって多少憂鬱になってしまうかもしれませんが、気にせず沢山出してみるのが良いです。一人ブレストです。「振り返り」をしている人などは以前の振り返りを参考にしたりすると良さそうですね。ちなみに私がどちらかと言うと課題に気付きやすい人間だからか、上記がネガティブな表現になっていますが、「仕事で活躍できるようになる」という要素の分解だと「コードを書くのがはやい」というような、ポジティブな表現で結果が表現される人もいるでしょう。どちらでも大丈夫で表裏一体だと思っていただければ良いかと。

分解したものを整理し、気づいたものを追加する

  • 開発についてのポイント
    • コード自体について
      • コードが仕上がるのが遅い
        • コードを書くのが遅い
        • レビューで突き返しが多い
          • コードにバグが多い
          • 関数の名前がいつも適切にできない
    • もっと大きな機能を実現できるようになれないといけない
    • 人の話からどういう機能が必要か提案できるようになりたい
  • コミュニケーションについてのポイント
    • 仕様の理解不足で間違ったものを作ってしまった
    • 「なぜ早く相談しなかった?」といつも言われている
    • 相手が理解しやすいように説明することができない
  • 全般的なもの
    • 同じ失敗を何度も繰り返してしまう

少し整理してみました。数を出している時は内容の粒度がバラバラなので、うまく原因と結果を意識できるとやりやすそうです。例えば「コードを書くのが遅い」と「レビューで突き返しが多い」は結果的にコードが完成するまでに時間がかかることなので新たに「コードが仕上がるのが遅い」とまとめています。

こうやっていくと、新たに気づいたりもします。追加したり整理したりしましょう。

  • 開発についてのポイント
    • コード自体について
      • コードが仕上がるのが遅い
        • コードを書くのが遅い
          • どこを変更したら良いのか考え込んでしまう
          • 既存のコードの把握に時間がかかる ★1
        • レビューで突き返しが多い
          • コードにバグが多い
            • 既存のコードの影響している範囲が掴めていない ★1
            • 動作確認が足りていない
          • 関数の名前がいつも適切にできない
            • 「良い名前」のストックが無いからでは? ★1
    • もっと大きな機能を実現できるようになれないといけない
    • 人の話からどういう機能が必要か提案できるようになりたい
  • コミュニケーションについてのポイント
    • 仕様の理解不足で間違ったものを作ってしまった
      • 一旦自分の理解を誰かに確認すればよかった? ★2
    • 「なぜ早く相談しなかった?」といつも言われている
      • エラーで動かないことで頭に血が上っていて声をかけられない ★2
    • 相手が理解しやすいように説明することができない
      • 緊張してうまく話せない ★2
  • 全般的なもの
    • 同じ失敗を何度も繰り返してしまう ★3

星をつけてみたのは、比較的大事なことで、どうやら同じような根っこでは無いかと思われるものです。

  • ★1 は「ソースコードが読めていなかったり、内容把握ができていない」という事
  • ★2は「誰かに話しかければ良いところを、(おそらく上手に話せないために)端折ってしまって失敗している」という事
  • ★3「同じ失敗を何度も繰り返してしまう」は結構クリティカルなのでどうにかしたいですね。"改善できない"という事になりますし。

この例の人の場合には、ソースコードの読み力を上げることはかなりの効果がありそうであるし、もう少し人に気楽に話せる状態になることは大事そうです。また、そもそも何度も同じ失敗を繰り返すというのは改善を阻むのでどうにかしたいですね。

アクションを見つけて、期限を決める

ポイントは見えてきたのでそれぞれ改善を考えたいですが、長くなりそうなので少し巻きます。★1 は見えやすいので掘り下げてみましょう。

  • 先輩にこの課題点を相談してみる
    • いきなり対面だと難しそうなので文書でまとめた上で1on1で聞く
  • ソースコードを読む事について何か良い書籍が無いか探す
  • 社内の勉強会のテーマにできないか提案してみる(先輩たちはどうしているの?)
  • 実際の仕事の時に、コードを読む時間を適切に確保する。読みが浅そうな時は...どうしよう
    • 一旦先輩に相談してみる?

適切なアドバイスくれそうな人に整理して意見を求めたりするのは結構有効なので(特に同じような経験を乗り越えている人なら尚良し)、相談できそうなものは相談してみるアクションになりました。

ここまで落とし込めば、意味のある目標が見出せそうです。仮に先輩と相談するようなワンクッションを挟んで、色よい返事がもらえたりすれば以下のような具体的な形に落とせるかもしれません。協力を仰ぐのが難しいケースなら自分だけでできることに落とし込みましょう。

  • ソースコードの読み力向上に役立ちそうな本を5月までに2冊読む(実際どの本が良いのか私はわからないのだけども、それを探すこともこの場合目標の一つかもしれません。良い本あったら私も知りたい)
  • 社内勉強会で自分が弱点に感じていることをテーマに勉強会が開けないか、相談して実現する(4月までには一回やる)

こんな感じでしょうか。最終的には「いつまでに、何を」まで落とし込むの大事です。あまり年間トータルのような長期にこだわると「いつでもやれる」という心理になって進まないので、もし年単位の長期になっても月間◯回とか刻んでチェックできるポイントを作る方が良いと思います。上記の例はまず最低限のステップを進み、それからもう一度目標を立てるイメージで出してみました。

おしまいに

達成できずに終わってしまいそうなぼんやりした目標を、小さなアクションに落とし込むことで一歩ずつ進められるような内容に落とし込む過程を文章にしてみました。皆さんの新年の目標立ての参考になれば幸いです。

[PR] 新年の目標に「プログラマーとして転職する」というような内容を掲げた方、目標を達成するにあたり先輩たちに相談したいことありませんか?また「実際にどのような仕事になるのか」とか「転職する際にやってみた方が良い事」など先輩に聞いてみたりしたくないですか?なんと、ちょうど良いイベントを1/25に行うのでチェックしてみてください。

ms2sato.circlearound.co.jp

「生殺与奪を握られている」という錯覚に気づくこと

f:id:ms2sato:20191231151112j:plain

はじめに

年末なので、いつもの友人Sと飲んでいた時の話より。

ms2sato.circlearound.co.jp

前回彼に聞いた「美味いフグを食べながら熱燗飲むとメッチャ美味い」という話を受けて、フグをまともに食べたことない私にその気分を味あわせてくれる為のフグ忘年会を行うことになった。

店に入って席に着くなり「ちょっと報告があって。来年から中国にゆくことになった。」と。

雇われている時に持ってしまう「下手にコトを起こせない」という心理

聞くとどうやら中国で新たに事業立ち上げをするメンバーに選ばれたらしい。3年程、嫁と子供を置いて単身赴任だそうな。

S曰く「転職もしようかとも思ったんだけどね」 前回夏頃に会話した時になんとなく仕事に関して全力投球ではない感を感じていたが、そういう中での話なら転職を選びそうなものではないか。

「なんとなく『ここまでしてダメなら』というところまで付き合ってみようかなと思ってね。今の現場と環境を変えらえるならそれもいいと思ったんだよ。」

そういうものか。自分とは違う判断基準を持っているのだろうなと思うし、ヤツもそう思われていることは気づいているだろう。

色々聞いている中で 「嫁と色々と話してたら『予想通りいかないことがあっても私も働くし、好きに選択したらいいよ』という話があって、なんか吹っ切れた」 という言葉からSはいい人を嫁にしたんだなと感じたし、それは素直に伝えておいた。彼の表現を借りるなら「運命共同体なので、親兄弟よりも信頼が強い」とのことだった。

そんなことがあってから、彼自身も言いたい事を発言するような事を上司なり周囲にできているとも聞いた。なるほど。そういう効果もあるんだな。つまり「別に辞めてもいいや。辞めても最悪の事態にはならない。」という心理になったんだろう。

この感覚は、自分が若い頃に仕事をしながら持っていた感覚に似ている。もともと社員という形で社会に出なかったからか「別にこの場所でうまくいかなかったとしても、元に戻るだけだ。だったら我慢ばかりする必要はない。」という心理。それがある種の思い切りの良さにもなるし、自分の軸を維持して行動できる原動力の一つだったと思う。

それと同じ感覚に、彼は嫁さんの言葉からたどり着いたんだなと、二人で合点した。

Sは「自分は成長が遅かったな」と言っていたが、こういう感覚は大勢と同じ流れに乗っている時には気づきにくいものではなかろうか。単純に気づける経験が目の前にあったかどうかだと思う。それに、彼が手に入れた今の経験値と成長は、今の家庭丸ごとひっくるめて出来上がっているのだから、ただの強がりから始まっている私のそれよりも余程強固に感じられた。

あんまり家庭を羨んだりしないのだが、彼と彼の嫁の関係はちょっと良いなと思ったりしている。

会社の生殺与奪と自立する社員について

会社がその権力を強くする一つの方法は「お前とお前の家族の生活は会社が握っており、そこから離れては生きていけない」と錯覚させることだ。実はそれは錯覚でしかないのだけれど、実際に会社から離れたことのない人には途方もなく大きな後ろ盾を失うような気がしてしまうのではないだろうか。この圧力によって「言いたい事を言えない、言わない」という状態を作ってしまう。実はそれは全体から見るとリスクなのだ。

そうでない形を目指すには「会社に依存するのではなく、自立した社会人として自分は外(別の会社や個人事業でもなんでも)でも仕事ができる」という事を名実ともに実現する事なのだろう。自分は元々会社組織が好きではないので、できればメンバーが個として独立できるレベルの能力を持った上で一緒に働けることを目指していきたい。

昨年、今年と新しいメンバーを迎えたけれど、最初の一年で目指しているのは彼らが「フリーランスしたい」と思った時にできる程度の技術力と人間的能力を身に付ける事だ*1。それは経営としてはリスクになるのだろうけれど、メンバー全員の幸せが大きくなる方へ舵を切るならこの方針で間違っていないはず。

もしも個人で活躍できるようになった途端に出て行ってしまうなら、そういうものだと割り切るしか無いだろう。そういう一時的な拠り所としての価値しか認められていない会社を省みる必要がある。私もまだまだ道半ばだと思わざるを得ない。

おしまいに

学びの多い場だったので、記しておきたいと思ったポイントを置いといた。未来の自分が読み返して思い出せる程度は書けているはず。

とりあえずふぐ刺しの実績解除をできたのだが、熱燗と一緒に食べると確かに美味だった。こうやって経済レベルが下げられなくなりそうな自分が怖い。

[PR] 直近のイベント

主にプログラマーとして転職したい方向けに先輩エンジニアの経験談や今だから思うことを色々聞けるイベントやりますよ! techdrive.connpass.com

*1:もちろんフリーランスはそれだけあればできるものでは無いが、最低限持つべきものはあると思う

プログラマーの現場経験1年くらいの人に就活〜現場の仕事まで聞いてみませんか?

「プログラミングを仕事にしたい!」と思っている方や既に行動始めた方に向けて、弊社メンバーが企画したイベントが来年開催されます!あまり色々聞けないこともクローズドなイベントでツッコンで聞いてみると、あなたの欲しい情報が手に入る筈ですよ。

techdrive.connpass.com

就活前や就活中、以下のような不安ってあったりしませんか?

  • 仮に実際に就職できたとして、どんな働き方になっていくのかのイメージがわからない
  • 就職したいならどういうアプローチがあるのか
  • 就職を目指した時にやったほうが良い事があるなら知りたい

こういうことを色々な切り口から会話できるような場所を用意しました。大きく2パートにしています。どちらも時間の余裕を多めにとって、疑問を余す事なく聞きだせるような場づくりです。

  1. 登壇した方ご本人の目線からの自由なプレゼンを聞いた上での質疑応答
  2. 緩めの懇親会で抱えている疑問をジックリ聞く

登壇者については弊社の個別トレーニング受けた人になってしまっているので以下のような雰囲気です。多少のバイアスがある事はご理解くださいませ。

  • システム開発の受託、スタートアップ/自社サービスはバランス良い
  • 言語はRuby中心。お一人がiOSでSwift。

世間では様々なことがTwitterに流れてきたりするので「確からしいことがよくわからない」という方は多いと思います。生に近い最新の情報に触れることできっとあなたのお役に立てるはずです。

techdrive.connpass.com

「俺はお前のママじゃ無い」をカッコよく言おうと思ったら「自己管理型」という言葉が近いらしい

f:id:ms2sato:20190722174503j:plain

はじめに

自分なりにやっていることや考えていることについてうまい名詞があると他人に伝えやすくなると思います。 最近社内で伝えていたことに近い言葉が無いか探してみたら、少し前に目にした「自己管理型」という言葉が近そうだったのでメモしておきます。 ただ、実際にはチーム全体の自主性を考えた言葉の様子なので、私の思うそれとは若干違うのかもしれません。

私の考え方

  • 自分のタスクの管理は自分でできること
  • 気づいたことや問題と思うことを個々のタスクの中で感じたら、早めにまとめ役に相談して良いこと(勝手に忖度して引っ込めずに積極的に相談して良い)
  • 情報の流れはトップダウンよりもボトムアップの方が活発

なんとなく過去私が知っていた組織のパターンだとあまり上記の感じになっておらず、まとめ役がいちいち確認しているような気がします(ポーリングっぽい感じ)。そのタイミングを定例的にするか都度にするかはわかりませんが、全体像はまとめ役だけが理解しており、その人の手足を延長するような形でそれぞれのメンバーが存在しているイメージです。

求めるのはもう少し勝手に動いてくれるもので、手足が伸びたと言うよりも、良きに計らってくれて信頼が高いイメージでしょうか。放っておいても自分で管理してくれる雰囲気です。

その為の条件の一つは「自己のタスク管理を個人で行える」ということです。以前タスクの抜け漏れが多いメンバーによく言ってたのは「俺はお前のママじゃ無い」的な話でした。タスクの抜け漏れ自体はツールを上手に使うだけでかなり改善できるもので、「基本的にタスクが抜けるもの」という観点のチームと「基本的にタスクが抜けないもの」という観点で進められるチームでは信頼感がまるで違うと思っています*1

ところで「俺はお前のママじゃ無い」は、表現としてはわかりやすいものの、あまりカッコよく無いですね。

世間の内容を少し調べてみた

www.infoq.com

自己組織化について論じている文章ですがここで言う 自己管理型チーム という言葉は私の理想と近そうです。「誰に責務を与えるか」は私が決めていますが、最終的に「どのように進めるか」はアサインされた人によって決められていくイメージですね。もっと上の権限を与えていくのも良いのかもしれませんが、メンバーの報酬や獲得して欲しい経験は私が握っていることが多いので、「自己管理していて欲しい」ということに集約されるのでしょう。

結果として期待していること。実際に起こること

以下のような感じですかね。

  • 「順調」という報告よりも「問題の相談」や「不安点の確認」のような 現在や未来のスムーズな進捗を確保する ための行動が増える。
  • 問題があれば勝手に相談くれるため、基本的にはこちらから義務感を持って話しかけなくともよくなる*2
  • まとめ役側のコストの低下

気をつけている事

物事よくわかっている人ほど「まとめ役の時間が貴重だからあまり話しかけてはいけない」と思ってくださるので積極的に話してくれなかったりしますが、個人的にはどんどん聞いて良いと思っています。問題や不安は前提知識が適切に伝わっていない場合にもよく起こりますし、必要な情報が揃っていないサインとも思います。この辺りを「まぁ、いっか」と放置したり「時間を奪う」と忖度した結果、あとでより大きな課題になって返ってくる事が多いのでは無いでしょうか。とりあえず相談しやすい空気をこちらが作り続けるのは結構大事ですよね。ちなみに自分の場合

  • 相談されたら出来るだけすぐ聞く。できない時は「xx分後」などと発信してこちらからアクションする。
  • 伝わっていなかった何かがあっても極端に不機嫌にならない。伝えたことを取りこぼしている様子ならこぼさない工夫を一緒に模索する。
  • 基本的にポジティブに聞く。問題や不安を増大させずに解消する方向へ舵を切る。

おしまいに

あんまりまとまってませんが「そんな感じに日々考えていますよ」ってことで。

*1:最終的に自身に合うツールや管理方法を確立してくれたので、件のメンバーのタスク抜けはとても減り、信頼できるようになりました

*2:私は無駄に話しかける時もそこそこあるんでついでに教えてもらえたりしますが

「フリーランスになればリモートワークができる」チョット待って!

f:id:ms2sato:20190516174404j:plain

はじめに

Twitter見てたら流れてきた話に反応します。 「『フリーランスになればリモートワークができる』という言葉、解釈が複数あるので気をつけてください」という話です。伝え方によってミスリードを起こすことができます。

私はプログラマについてしかよくわからないのでその観点で読んでください。あと、法律の専門家ではないので何か間違ってたらそっと教えてくれると、とっても嬉しいです。

前提の契約形態の知識(知ってる人は飛ばしてください)

前提となったTwitterの話題では契約の話も触れられてたのでちょっとおさらい。 フリーランスは「業務委託契約を結ぶ個人事業主」とさせてください(他にあるかは知りませんがこの辺りが崩れると事情が変わるかもしれません)。

契約でよくある形式は以下2つかと。まとめて業務委託契約と言ったりします。中身としては以下二つのどちらかを指しているはずです。私は専門家ではないですが、これくらいがポイントだと思えばいいかと。また、契約の形態に特徴はあっても優劣は有りません。そして契約なのでもしも不利だと思うのであればフリーランスなら自分で交渉しましょう。

請負契約

  • 「〇〇な仕様のものをいつまでに納品」というような「いつまでに、何を」を約束します。
  • 多くは全部完成して納品し、検収(お客様の確認)が終わったら請求書を書いてお金をいただきます。
  • 通常瑕疵担保責任が発生します。例えば「一年以内に不具合(仕様と合致しない事を不具合とする)が発生した場合には無償で修正する」など。

準委任契約

  • 「現場の指示に従って技術力を提供します」というような、時間貸しのような約束です。具体的な作業の内容は現場に任せられます。
  • 月や日、時間など稼働の単位を決めて、例えば月末などに「今月は◯時間働いたからおいくら万円」のような請求書を書いてお金をいただきます。
  • 通常瑕疵担保責任が発生しません。あくまで技術力を指示通りに提供した事で契約は満たしています。

※注意

契約書の分類は通例このような形であると言えるけれども、その内容は書かれている文章によって変わります。上記は分類としてはそういう形であると理解したほうがいいです*1

契約の形式と、労働の環境は別物です

「どの契約をすれば、リモートワークができますか?」と聞かれたら、どれでもできますし、どれでもできない可能性がありえます。書類の内容にどこで作業するかが明記されていればその場所に必ず縛られますし、書かれていなければお互いの相談によって決めることになるでしょう。

つまり「フリーランスになれば(必ず)リモートワークができる」というようなことではなく「フリーランスになれば(契約の内容次第で)リモートワークができる」ということです。どういう文脈で相手が言葉を発しているかにもよりますが、括弧に表現した部分について都合の良い解釈をしないように注意が必要です。

「そもそも、フリーランスにならなければリモートワークできないの?」

端的に言えば会社次第です。皆さんもよくご存知かとは思いますが、最近では「働き方改革」の風潮もあり会社が副業やリモートワークを実現することも増えていると思います。「フリーランスにならなければリモートワークはできない」と決めつけるのは早計です。

「リモートワークできる契約をしたいんだけど」

契約書を取り交わしたり、更新する際にご相談されるのが順当かと思います。ただ、私の観点だと以下のようなポイントはあります。

  • 「リモートでも成果量が下がらないだろう」というある程度の確からしさがあること。もしくは下がっても受け入れられる現場であること。
  • リモートではテキストコミュニケーション中心になりがちですが、この辺りが苦手ではないと推察できること。
  • 対面で確認ができない状況でも、ゴールを間違えないようなコミュニケーションを取る力量があると推察できること。

「請負で契約すれば」と思うかもしれませんが、世間でよく言われることに「フリーランスはすぐ逃げる」という事があります。都合が悪くなるといなくなってしまうフリーランスはよくいる様子です(私の知り合いにはそういう方はいないのでよくわかりませんが、経営者の方と話をするとそこそこあるようです)。請負で期限ギリギリに連絡が取れなくなってしまうようなことになれば事業としては痛手なので、ただ請負にすれば良いというものでもありませんよね。

結果的にリモートワークできるような立場を手に入れるには「仕事をある程度うまく進めるだけの仕事調整力やプログラミング力などの力量があること」というのはかなり確からしいことだと思います。

「業務未経験です。リモートワークしたいです。」

先述のようなポイントを抑えていると証明できる何かがあればできるかもしれませんが、ほとんどの方にはそれができないような気がします。よほどの幸運がなければ難しいのではないでしょうか。最初に一定の期間対面の時間を作りながら信頼を作ってリモートをいれていく人はいそうです。

私のプロジェクトでよく発生するリモートワークは GitHub-Flowを使い、Issue単位で仕事をこなしてもらう形& 時給時間単価での準委任契約です。プログラマとしてチームに参加するならこの辺りができると良いかもしれません*2

おしまいに

日本語難しいので、複数の解釈の余地があるようなことは丁寧に確認すべきかと。また、誰か一人が言っていることだけを盲信するのではなく、世間一般ではどうなのか、などの情報を自分から集めにゆくのは大切なことかと思います。特にフリーランスになるような方なら自分で自分を守らなければ。誰かが守ってくれるというような立場では無いですよね。

*1:例えば契約書を取り交わした後にE-mailなどで別の内容を取り交わして内容を上書きすることもできます。詳しいことは調べてみてください

*2:弊社のトレーニングはこの形式を基礎に作っているので、十分訓練した人は私たちのチームでうまく組めるだろうと考えています。いつも自社の宣伝をねじ込んでいくのは仕様です

「モデルの中からPOROを呼び出すのはどの程度認められるのか」気になります

はじめに

tech.medpeer.co.jp

この記事読んで思ったことを誰にともなくコミュニケーションしてみたくなったので書いてみます。当該の記事はリファクタリングの考え方としてとても好きです。その一方で過去私がとても苦しんだ事と同じ課題(もはやトラウマみたいな)を感じたのでアウトプットしてみたくなりました。

私の感覚

長くなるので後の方に色々細々した気持ちを書きますが、今の私はモデルのリファクタリングについて下記の記事をかなり重要視しています。その観点で当該のサンプルをリファクタリングするとどうなるかを書いてみると良いと思いました。

techracho.bpsinc.jp

上記記事に従うと、今回の場合「処理が複雑になった(という前提ですよね?)」と考えてServiceを採用するか、「あるユースケースにおける保存処理に介入する」と考えてDecoratorを採用するのが妥当な気がします。というわけで二つ書きました。そして私ならこれらの二つのどちらかがシックリくると考えて、元記事でのリファクタリング結果には意見を提示すると思います*1

Serviceを採用した場合

class Message < ApplicationRecord
  has_many :mentions
  belongs_to :creator, class_name: 'User'
  belongs_to :channel

  def here?; end # 省略
  def channel?; end #省略
end

class MentionNotifier
  def self.call(message)
    self.new(message).call
  end

  def initialize(message)
    @message = message
  end

  def call
    ActiveRecord::Base.transaction do
      return false unless @message.valid?
      @message.save!
      create_here_menthin if @message.here?
      create_channel_mention if @message.channel?
    end
    @message
  end

  private

  def create_here_mention
    members = @message.channel.members.active - [@message.creator] # これはMessageのメソッド化しそうですが、本題とはずれるのでこのまま
    create_mentions(members)
  end

  def create_channel_mention
    members = @message.channel.members - [@message.creator] 
    create_mentions(members)
  end

  def create_mentions(members)
    members.each do |member|
      @message.mentions.create!(to: member, chennel: @message.channel)
    end
  end
end

# 使い方(create アクションの中の想定)
message = Message.new(params)
MentionNotifier.call(message)

Decoratorとしての切り出し

class Message < ApplicationRecord
  has_many :mentions
  belongs_to :creator, class_name: 'User'
  belongs_to :channel

  def here?; end # 省略
  def channel?; end #省略
end

class MentionNotifier
  attr_accessor :message

  def initialize(message)
    @message = message
  end

  def save
    ActiveRecord::Base.transaction do
      return false unless @message.valid?
      @message.save!
      create_here_menthin if @message.here?
      create_channel_mention if @message.channel?
    end
    @message
  end

  private

  def create_here_mention
    members = @message.channel.members.active - [@message.creator] # これはMessageのメソッド化しそうですが、本題とはずれるのでこのまま
    create_mentions(members)
  end

  def create_channel_mention
    members = @message.channel.members - [@message.creator] 
    create_mentions(members)
  end

  def create_mentions(members)
    members.each do |member|
      @message.mentions.create!(to: member, chennel: @message.channel)
    end
  end
end

# 使い方(create アクションの中の想定)
message = MentionNotifier.new(Message.new(params))
message.save

モデルの中からPOROを呼び出すのはどの程度認められるのか

「今回選ばれた例が通知をする処理だから上記のような形の方がシックリくるのではないか」

と思われてしまうと本題と外れてしまうので章立てしました。私がRailsでコードを書き始めて当初悩んだことの一つがこの「モデルの中からPOROをバンバン呼び出すのはアリなのか」ということなんです。

私にとってJavaの業務系でのコードのスタイルがキャリアの初期にあった為か、POJO を中心とする書き方が身についており、肥大化するモデルの処理や、通知などの内容は元記事のコードのようにモデルの中からPOROを呼びたくなっていたんです。ただ、ロジック層に入ってPOROから(ActiveRecordに強く縛られた)モデルを呼び、さらその中で業務に関連したPOROを...と呼ばれるのが不自然に感じられていたんですね。

そういう中で出会ったのが先に紹介した肥大化したActiveRecordモデルをリファクタリングする7つの方法(翻訳)の記事です。この記事は悩んでいた私に一つの考え方を指し示してくれました。「基本的にModelを渡す形で良い」という事です。この記事に出会ってからは私が抱えていた悩みはスッと晴れました。手本とするのに適切であると思っています*2

ただ物事には例外がつき物なので「〇〇なケースでは認めて良いのでは?」というのもありそうです。私だとSTIしている複数のクラスからそれぞれの型に関連したPOROを生成させるメソッドを作りたいと思うことはよくあります。これは認めても良いかもと感じています。

そんな私が今回の記事を読んだ時に「あれ?私の過去の悩みって結構無駄だった?」なんて変な汗が出てしまったのでした(笑) というわけで、この話題について多くの方々がどのように考えていらっしゃるのか大変興味があります。もしも何か良い指針があれば私もそれを知りたいのです。

おしまいに

特にRailsでは慣習や大勢のパターンに合わせた書き方を強く推奨することで、多くのプログラマーがプロジェクトを移動しても活躍しやすいという土壌があると思っています。少し前にも「Serviceクラスをどのように書くべきなのか」などの話題があったりしましたね。こうやって「xxxなケースはyyyな解法が概ね良い*3」という事が積み重なってより良い開発をお互いにできる気がしています。ということもあり「私はこうかなー」というのを書いてみました。

また、スルーしてしまいましたが元記事の主題であるサービスクラスの書き方については、下記に倣っている様子なので「ですよね〜」と思って拝見していました*4techracho.bpsinc.jp

*1:開発の仕事の中でレビューする際に、私個人の哲学を押し付けて良い場合は限られていると考えています。だからこういうシーンでは大抵自分の意見を提示してみてコミュニケーションを取ります

*2:自分ところのトレーニングでもこの内容はよく紹介しています

*3:最高で無くても良く、一般的に皆がある程度納得できるものであれば良いというイメージです

*4:私だとメソッド名固定に強いこだわりは無かったりしますが

「Pythonによるはじめての機械学習プログラミング(ジェンガ本)」は機械学習の素晴らしい実践的なとっかかりを提供しています

はじめに

著者の一人、島田さんから献本いただきました。ありがとうございます。 知り合った頃は学生だった島田さんが、CTOとして大活躍して、今度は本まで出されるということでオッサン目頭が熱くなります。

GWの最初にとにかく読み終えておきたかったので初日の課題にしました。いつもならコードを試しながらなのですが、この本に限っては私が機械学習についてあまり知識がない為「手を動かす前にまず全体を読み切ってしまおう」という流れで、先刻読み終えたところです。厚さの割にスイスイ読めました。

勧めたい読者像

私の理解ではこの本は「機械学習に無知なシステム開発者に対する、素晴らしい実践的なとっかかり」を作るための一冊だと思っています。もう少し分解して対象者を書くと以下のような感じでしょうか。

  • Pythonを扱ったことがある、もしくは書かれたPythonのコードを処理を類推しながら読み進められる人。
  • 機械学習全般には詳しくないけれども、とっかかりになる道具の扱い方や解説を求めている人。
  • 機械学習ライブラリを扱った際に、どのようにWEBなどのシステムに組み込むのかのとっかかりが気になる人。

また、機械学習というと画像や文章など様々なところで応用がなされるものだと思いますが、本書で主に解説されているのは以下でした。

  • 教師ありデータを元にしたデータ予測(scikit-learn)
  • 自然言語解析を利用した類語検索や文書分類(Word2vec, Gensim, PyTorch)

このあたりに興味のある人は特に満足度が高いでしょう。画像や動画を処理したいような方は別の入り口から入る方が良いかもしれません。

全体的な章立て

大きく分けて4部で構成されています。

  • 第1章 Pythonによる機械学習プログラミングの準備
    • WindowsやLinuxなど各環境ごとのインストールから、Visual Studio Codeのデバッグ実行までスクリーンショットなど交えて丁寧に解説されていました。まだ試してはいませんが、これに沿ってやればそれほど苦しまずに環境を手に入れることができそうです。
  • 第2章 Pandasによる前処理とデータの分析
    • 機械学習を実際に始める前に行うべきデータの整理や基本的な操作について書かれています。こちらもかなりページを割いて丁寧に手法が示されていると感じました。
  • 第3章 scikit-learnではじめる機械学習
    • 機械学習についての導入から実践的な内容が記されています。詳しくは後述。
  • 第4章 GensimとPyTorchを使った自然言語処理
    • Word2vec を用いた単語のベクトルを使ってベクトルの引き算から単語を推察したり、文書を分類したりします。

読み進めて感じたこと

この本は最初から読み始めると第2章が長い割になかなか想像している内容が出てこない為、やきもきしてしまうかもしれません。 「何かデータを処理するいわゆる『機械学習っぽさ』を体験したい」という人は第3章から入ってみても大丈夫かもしれません*1。この章を読んでモチベーションを高めてから第2章でも良い気がします。ただし本書は「第2章も含めて初めて完成する」と思うので以下に記します。

3章の内容はとても良いバランスを突いています。

  • 機械学習についての概論的な導入、現場における課題感など
  • データとコードを使った具体的な処理
  • 実際にWEBのシステムに組み込むための考え方

まで通して説明されているのは、冒頭に私が書いた「とっかかり」を与えたいという本書の目的感によるものではないでしょうか。

また、折に触れてS3にデータを置いておく話が出るとか、サンプルがWEB-APIを作成するものであったり、解説にマイクロサービスという言葉が出ていることからも「実際のシステム開発の現場」について著者が強く意識していると感じます。

そしてこの第3章を読了すると、丁寧で多少冗長にも感じた第2章がいかに大切なものだったかが見えてきました。第3章に倣って実際に大量のデータを扱おうと考えると、第2章の話題を避けて通ることができないはずです*2。第3章や第4章を完成するための大きなパーツとして第2章が存在していると理解しています*3

第4章は大量のテキストが行き交う現代のシステムにどうしてもやりたくなる自然言語の処理について書かれており、興味深く読ませていただきました。単語ベクトルという考え方を導入することで言葉の相関を整理することができ、それによって言葉の類推的なことができたり文書を分類することができるというものなので、実際の自分のサービスでもやってみると有意義な結果が得られそうに思います。

本を読んでフムフムするより実際に稼働しているシステムの情報を使って手を動かした時、4章の評価が適切にできるような気がしました。

おしまいに

とりあえずこれまで「機械学習難しそうだしよくわからない言葉いっぱい出てきそうだからなぁ」と敬遠していたシステム開発者だったらこの"ジェンガ本"は一度目を通してみて損がない一冊だと思います。弊社トレーニングで機械学習コース作るときは教材にしたいです。

Pythonによるはじめての機械学習プログラミング[現場で必要な基礎知識がわかる]

Pythonによるはじめての機械学習プログラミング[現場で必要な基礎知識がわかる]

  • 作者: 島田達朗,越水直人,早川敦士,山田育矢
  • 出版社/メーカー: 技術評論社
  • 発売日: 2019/04/19
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログを見る

*1:このことは本書の「はじめに」にも書かれているそうですが私読んだはずなのにスコーンと抜けてました ^^;

*2:私だととりあえずGoogleDocsに貼って色々コネコネしてしまいそうですが、そんなことしなくていいんですね...

*3:私はまだ機械学習を利用したシステムを組んだことはありませんが、第2章のように「雑多なデータを扱いやすい形に編集したり、可視化して傾向を掴むなどすることは実際にシステムに組み込むよりも時間のかかる大切なプロセスだ」とのメッセージではないかと感じています