3
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

Organization

Classiエンジニア新人研修での学び方の学び

Classi Advent Calendar 2019の16日目の記事をご覧いただき,ありがとうございます!
2019年新卒エンジニア@willsmileです.自称コーヒー好きですが,コーヒーのことを語ると,教育と学習の方に“脱線”してしまい,「結局,教育のほうが趣味なんじゃないの」と最近自覚した者です.

まえがき

本文では,Classiエンジニア新人研修を通じて,自分自身が「気づいた開発について新たな観点(の一例)」を語り,将来の自分,あるいは他の人にも参考できるように,「どうやって気づいたのか」を一段上の観点から言語化することを試みます.

本題

研修の概要

Classiエンジニア新人研修のカリキュラム担当者が業界で有名なRubyist@igaigaです.Classi入社前に@igaigaさんが著者である「ゼロからわかるRuby超入門」という本を持っています.それを読んでいて,Ruby言語の概念の厳密さと理解しやすさのバランスをよく取れている本という印象を残っています.@igaigaさんとの初対面の自己紹介で,「あの本の著者だ!すごい!」というびっくりから,研修の一日目が始まりました.

研修の題材と進み方について,4日目の記事@yukoonoさんが紹介したように,万葉さんの公開カリキュラムにベースにして,各課題ステップにおいて,実装案の議論・検討,コーディング,コードレビューと修正といった「疑似体験」のサイクルが回します.このプロセスを通じて,わかったこと・気づいたことをメンターと話し合いながら,一緒に整理することで,これからの業務とつながるように,自分自身の理解を構築(再構築)していきます.これからは,実装案の議論・検討について,一個の例を通じて,自分自身の気づきを紹介します.

気づきの経緯

カリキュラムで定義されたタスク管理システムの要件の一つとして,「タスクに優先順位をつけたい」があります(以下の図がシステムの目標状態のイメージ).

Untitled.png
図1.タスクとその優先順位(イメージ)

カリキュラムのステップ6において,この要件を満たすために,モデル作成の段階では,タスクの優先順位をValueがStringのEnumで定義という実装案を考えていました.そう設計した理由として,現在の優先順位の仕様(例:低,中,高)を将来的に変更(例:低,やや低,中,やや高,高)があった時にも,対応しやすくなるからです.

class Task < ApplicationRecord
  ...
  enum priority: {low: "low", normal: "normal", high: "high"}
  ...
end

この実装案を採用して,ステップ17までに進んだ時に,「優先順位を使って,タスクをソートできるようになる」といった仕様に対して,優先順位の順番を表す情報がシステムにはなかったため,ソートの実装ができなくなりました.それを解決するために,以下のようなコードを書いてみました.それは「そう!」,自分が書いたコードなのに,いま改めて読んでも驚きほどの複雑なもので,コードのリーダビリティーがかなり低くなりました.

class Task < ApplicationRecord
  ...
  enum priority: {low: "low", normal: "normal", high: "high"}
  PRIORITY_ORDERS = ['high', 'normal', 'low']

  scope :priority, -> (order_of_priority) {
    if %w[asc desc].include?(order_of_priority) 
      if order_of_priority == "desc"    
        priority_orders = PRIORITY_ORDERS   
      elsif order_of_priority == "asc"  
        priority_orders = PRIORITY_ORDERS.reverse   
      end   
      order_by = ['CASE']   
      priority_orders.each_with_index do |priority, index|  
        order_by << "WHEN priority='#{priority}' THEN #{index}" 
      end   
      order_by <<'END'  
      order(order_by.join(' ')) 
    else    
      raise ActiveRecord::StatementInvalid  
    end
  }
end

この状況を整理して,最終的に,優先順位を”マスター化”する(タスクのAssociationで定義)という実装案にしたが,「なぜこうなったのか?」,「そもそも,このような仕様って,どう選択すれば良いのか」といった疑問を持ち,先輩たちの意見を聞きました.

学び方の学び

更に,この経験をメンターと一緒に振り返って,以下のようなかたちで,それぞれの実装案について,様々な意見をまとめていました.

表1.実装案のメリットとデメリットの比較
Untitled 1.png
注:上の表には,コストという概念を使っているが,この例の場合.プロの人にとって,実装のコストの差があまりなく,適切ではないかもしれないが,ここの意図は「コストというよく見かける判断軸を登場させる」ことである.

それを通じて,「正解って,実はないですね!」ということが初めて気づきました.つまり,それぞれの実装案はメリットとデメリットがあって,どれにするかが具体的な状況に合わせて選択することが重要です.例えば,自分が「最適だ」と思っていた実装案③でも,「何でもかんでもマスターデータにすると,管理するのは大変になっちゃうよ」というデメリットがありますし,最初に却下した実装案①でも,「後からソートしやすいね」というメリットがあります.問題の本質は,コスト,機能の拡張性といったことについてどう考えているのです.もちろん,それについて,ディベロッパーだけではなく,デザイナー,プロダクトマネージャーなどの異なる役割の方を含めて,一緒に議論して考えることは大切だと考えます.
このように,自身の「うまく考えていなかったことで,やっちゃった」経験から,様々な人の知恵を借りて,経験者の補助で振り返ることを通じて,プロのように考える「判断軸」(もちろん,これは氷山の一角にすぎない)を見つけていました.

あとがき

その2ヶ月間の研修を通じて,@igaiga先生,メンターの@nagatashinyaさん,またたくさんのエンジニアの先輩たちのおかけで,今でも「生きている経験」をたくさん得ました.以下の研修卒業の時に,自分のTwitterのメッセージで,本日の話を締めます.
Twitter_message.png
明日の投稿は,メンターの@nagatashinyaさんです.お楽しみに!

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
3
Help us understand the problem. What are the problem?