yutaroのブログ

技術や思想について発信

2年間エンジニアアルバイトして,1番大事だなと思ったこと

はじめに

これはあくあたん工房アドベントカレンダー2019,16日目の記事です.

記事の内容はポエムです.頑張って書いたねという優しい心で読んでください.

他の記事はこちらを参照してください.

adventar.org

記事を書いてる人

まずは私のエンジニア歴がどのようなものかをご紹介します!

  • 中学生ぐらいでCを触ってみるも挫折して,以後触っていない
  • 大学は情報工学
  • 大学院は情報工学専攻
  • 大学院を休学し,週2-3日ぐらいのエンジニアアルバイトを始める
  • ハッカソンなどには基本参加していない
  • ゲーム作りをして,未完成ながらデジゲー博へ出展する

こんな感じです.

ものづくりとしてプログラミングを始めたのはここ2年ぐらいの若造だと思ってください.

若造が気付いたエンジニアとして大事だと思ったこと

では,本題に入って行こうと思います.私が大事だなと思ったことは

「業務を理解すること」

です!

当たり前だろと思う方または業務ってなんの業務と思う方それぞれいらっしゃると思います.これから順に説明していきます.

そもそもエンジニアの仕事って何?

そもそも私たちエンジニアが作っているものって何なんだ?

定義は人それぞれあるかもしれませんが,ここでは「業務の一部のシステム化」としておきます.もっと平たく言うと「今手作業でやっていることを自動化して,効率あげていこう」って感じです.

業務を効率化すれば,商売にかかるコストも抑えられるし,作ったもの自体が売り物になることもあるでしょう.

上の内容にそぐわないものも多々存在するとは思いますが,ここでは上の定義を前提に説明していきます.

業務って何?

「業務を理解すること」って言うけど,業務って何よ?

業務とは「システム化して効率をあげたいもの」です.

例えば,新規事業や社内ツールなどです.

じゃあ,業務を理解するって何?

要するに

「今から作るものちゃんと理解してすること」

ってことです.

ふざけんな,当たり前だろ!と思うでしょう.

当たり前です.ですが,当たり前のことが簡単なこととは限りません.むしろ,ここができていないから世の中には悲しみを背負ったエンジニアの創作物が蔓延っているんだと思っています.

当たり前のことが当たり前にできる人はおそらく周りから優秀と言われている人たちでしょう.

世の中には当たり前のことが当たり前にできない人の方が圧倒的に多いです.だから,私たちはちゃんと意識をして良い仕事をしていかないといけないのです.

ここからは業務を本質的に理解していくために必要なものや業務をシステムに落とし込んでいく手段を私の知る限りでお伝えしていきます.

理解するために必要なもの

業務を理解していくために必要なものですが

  1. 業務に関する知識
  2. 業務の本質を聞き取るコミュニケーション能力

です.順に説明していきます.

業務に関する知識

業務をシステム化していくに当たって業務の知識は必須です.では業務の知識はどのように集めていくのか?

答えは業務に詳しい人に聞くです.

業務に詳しい人は特定の誰かに限らないです.営業さんや管理部,人事部,その他諸々,たくさんの人々が関わってくることがあります.新規事業ならば提案した人です.作るものによっては複数の人から聞き取ることもあります.

しかも,単純に聞くだけではダメです.何故かと言うと

「聞き出した業務が完全なものとは限らない」

からです.

単純に今の業務をシステム化することもできます.ただし,これを行うと多くの場合でシステム化した後,痛い目に合います.理由は業務は常に改善されていくからです.この変化に耐えうるシステムを作っていかなければなりません.

つまり,「システムが変更できないから業務を改善できない」状態になってはいけないのです.

また,システムを通じて業務を改善することもあります.システムを作っていく段階でより効率の高い業務にしていくことも仕事の一部です.

業務を通じて成し遂げたい目標があるはずです.その目標を聞き出し,業務の本質を理解する必要があります.本質を理解して作られたシステムは変更に耐えうるシステムになり,より効率の高い業務を生み出すはずです.そのために次で説明するものが必要になってきます.

業務の本質を聞き取るコミュニケーション能力

コミュニケーション能力と言われて,ッウ(絶命 となる人も多いでしょう.確かにコミュニケーションは難しいですが,ここでいうコミュニケーションはそんなに難しくないと思います.

初めて会った女の子に声を掛けていい感じになるコミュニケーション能力はいりません.

おっさん上司が若い部下と距離を詰めるためのコミュニケーション能力もいりません.

「チームメイトと良いシステムを作るために業務の本質を見抜いていく」

ためのコミュニケーション能力です.

じゃあ,具体的にはどうすればいいか?ですが,簡単です.

「解決策ではなく問題点に焦点を当てる」

です.

余談ですが,「問題点はいいんだ.解決策だけを持ってこい」と言う上司は基本無能…ちょっと言葉が汚ないですね.仕事をこなしているだけだと思っていいと思います.私はそう思ってます.何故なら持ち出してきた解決策が必ずしも最適なものとは限らないからです.自分の価値観だけで見つけだした解決策よりも,色んな価値観から見出した解決策がより正解に近い解決策になることが多いです.問題点を共有し,議論ができる組織は強い組織だと思います.その為には自分の意見を言えて,他人の意見を聞ける人が必要ですが…

話を戻します.

もっと具体的にいきます.「なんでその業務をしているんですか?」と聞くだけです.そして「なんで」をひたすら突き詰めていく.これによって,本質が見えてきます.

理由は簡単です.問題点を解決するための解決策だからです.解決策から遡って問題点を浮き彫りにします.その問題点をシステムによって解決していくのです.

今までのシステムを用いない解決策とこれから作るシステムを用いた解決策は異なるものです.システムを用いた解決策を提案するためには問題点を理解する必要があります.

ここからは具体的にシステムに落とし込んでいく方法について説明していきます.

業務を適切に切り分ける

今までに伝えた方法で業務を理解することができたとします.ここからが一番難しいところだと思います.今まで聞いてきた業務を適切に切り分けて,システムに落とし込んでいきます.

業務の切り分け方

業務の切り分け方ですが,これは絶対にこう切り分けると言うものがあるわけではありません.業務を理解して,議論し,切り分ける必要があります.ここが綺麗にできると後々痛い目に合うことが少なくなるはずです.

具体例をあげます.

「商品をネットで販売して,利益をあげたい」と言う案件がきたとします.その話を聞いていくと次のことが分かってきました.

  • 会員登録をしてもらって会員さんだけが商品を買える
  • 商品を一覧から検索してもらって,注文してもらう
  • 商品をカートに入れて,一気に注文できる
  • 支払い方法は代引きのみ
  • 注文が確定したら,配送会社に頼んで配送してもらう

よくあるECサイトです.開発者チームで話し合い,一つのECシステムとして作り上げようとしました.これが大きな間違いでした.

チームは無事要望通りに動くシステムを作ることができました.しかし,依頼主から次の要望が来ました.

  • プレミアム会員を作って,プレミアム会員にはより良いサービスを提供したい
  • 内容としてはプレミアム限定の商品やより早い配送など

チームは困り果てました.一つのシステムとして動かすことだけに特化したので,どこにどのコードがあるか,コードを変更した時の影響範囲,DB設計の変更による改修するコードがどこにあるか,これらが全く予想できませんでした.

本来であればこのECシステムは複数の業務に切り分けることができたはずです.例えば,

  • 認証・認可システム
  • 在庫管理システム
  • 在庫検索システム
  • 注文システム
  • 支払いシステム
  • 配送管理システム

などです.これらを別々のプロジェクトとして管理していれば,今回の要望は認証・認可システム,在庫管理システム,在庫検索システム,配送管理システムを改修すればいいと分かったでしょう.

この切り分け方は多くの場合,依頼主からは出てきません.話を聞いて,業務の本質を理解して,こういう可能性があるのでは?と議論を進めていくにつれて見えてくるものです.

もしかしたら,話し合いの最中により良い提案が出てくるかもしれません.例えば,「実は不良在庫が多くて困っているんだ」などの話が出てきたら,売り上げ管理システムを提案して,より効率的な在庫管理などを実現できるでしょう.

この切り分け方が適切な切り分け方だとは限りません.適切に切り分けているかは業務を改善していくにあたって,少ないコストでシステムを修正できるかどうかで判断するしかないでしょう.

かなり大げさな例ですが,業務を理解して,業務を適切に切り分ける雰囲気が伝わって頂ければ幸いです.

ここからは実際に実装していくにあたっての個々のシステムの設計方針について説明していきます.

どのようにシステムを作っていくか

業務を理解して,業務を適切に切り分けたら,実際にその業務をコードで実現する必要が出てきます.次の2つの設計方針が多いと思います.

これらについて説明していきます.

データ指向アプローチ

具体的に言えば,データ構造をしっかりと把握して,DBに落としみ,そのデータ構造をどのように見せるかという考え方です.

Railsのアクティブレコードなどはこの考え方に近いと思います.

この方法の長所は

  • 開発が早い

です.短所は

  • 可読性が悪い

です.

単純にデータのやり取りをするだけのコードを書くことが多くなると思います.DBからデータを引っ張るやデータをDBへ保存するなどです.

このコードはDBというシステムに引っ張られたコードになります.ですので,コードから実際の業務を理解することは至難の技です.コードを理解することと業務を理解することを要求されます.これが可読性の悪さに繋がります.

この設計方針は次のような場面に適しています.

  • CRUD機能だけの簡単なシステム
  • 管理することが少ないシステム
  • 改修がほとんどないシステム

簡単なシステムでほとんど機能が変わらない場合などはおすすめです.

ドメイン駆動設計

業務をコードで表す設計方針です.具体的な方法はググってみてください.正直よく分からんと思います.

先ほどとの違いは業務を表す部分と技術を表す部分を切り分けるということです.コード側で業務特有のデータ構造を持ちます.これはDBのデータ構造とは切り離して考えます.

そして,業務の流れをオブジェクト指向を用いて,表現していきます.

この方法の長所は

  • 可読性が高い
  • 変更に強い

です.短所は

  • 時間がかかる

です.

コードで業務を表すので,コードを読むことで業務がわかります.これが可読性の高さにひも付きます.

また,オブジェクト指向を用いて業務的なコードと技術的なコードを切り離します.これにより,データをどこから取得しようが,どんなDBを使おうが業務的なコードの部分に影響を与えません.

オブジェクト指向を用いて,これらを実現するパターンを戦術的設計と言います.例えば,

など色々あります.

実は最初の方に説明した業務の理解や業務の切り分けの内容もドメイン駆動設計の一部で戦略的設計と言います.

これら2つの設計を用いたものがドメイン駆動設計です.ここでのドメイン領域という訳が伝わりやすいです.業務全体領域や切り分けた業務領域などをドメイン駆動設計ではドメインやコアドメインサブドメインなどと名付けています.

戦術的設計だけを用いて,技術的な改善だけを施した場合は軽量ドメイン駆動設計と言われます.ドメイン駆動設計の提唱者的にはアンチパターンらしいです.

この設計方針は次のような場面に適しています.

  • 複雑なまたは複雑になりそうなシステム
  • 自社サービスシステム
  • 長期的に管理するシステム

長期的に利用して,変更が多くなりそうなシステムに向いています.

ドメイン駆動設計を理解するにはググって雰囲気を掴んで,以下の本を読むのがいいと思います.

実践ドメイン駆動設計 (Object Oriented SELECTION)

実践ドメイン駆動設計 (Object Oriented SELECTION)

この考え方は難しいと思います.私自身も1割ぐらいしか理解できてないです.ですが,理解してシステムを作っていくことができれば,いい仕事ができるはずと信じて勉強してます.

まとめ

長くなりましたがまとめです.

  • 業務の本質を理解する
  • 業務を適切に切り分ける
  • 適切な設計方針を選択する

これらが実際に仕事していく中で大事なことだと思いました.

あとがき

私自身もまだまだ経験不足で説明が至らない点が多々あると思います.特にドメイン駆動設計についてはまだまだ勉強不足です.

個人的な見解や誤った考察が含まれている可能性はありますが,生暖かい目で見守っていただけると幸いです.

人生の転機

今回は私の「人生の転機」とその後について述べていきたいと思います.

私の人生の転機は大学3年生の8月でした.

全てが嫌になり,後期が始まっても大学に行かなくなりました.

病院に行くと適応障害と診断されました.

原因は突発的なものではなく私自身の「性格」だと思っています.

しばらく,家にいて休んでいました.

自分自身が嫌いになりました.

周りのもの全てが嫌になりました.

特にこんな私に育てた家が嫌いになりました.

自殺も考えました.

ただ,怖くてできませんでした.

生き地獄でした.

生きていく気がないのに,死ねないのですから.

それから無気力になりました.

何もせずにボーっとする時期が続きました.

しかし,この先どうすればいいんだろうと考えると,このままじゃいけない気がしました.

とりあえず,アルバイトをしてみることにしました.

このアルバイトは3つほど転々としました.

長くなるので,カットします.

めっちゃ色々ありました.

1年が経ち,休学期間が終わりました.

まだまだ,治っていなかったのですが,授業だけには出ていました.

周りの視線が異常に怖かったのを覚えています.

自分で自分のことが異常だと分かっていたので,余計に怖かったです.

しばらくすると,段々と慣れてきました.

人間って図太く生きていけるようになってるみたいです.

すると,何を血迷ったか,ある女の子に告白をしようとしました.

この時の心情は分からないです.

おそらく,もう失うものが何もなかったので,頭がおかしくなっていたんだと思います.

この女の子はいわゆる幼馴染で地元でずっと遊んでいた子でした.

中学も同じだったんですが,ウブな私は段々と周りの視線を気にして,全く声を掛けなくなりました.

高校,大学は全く会っていませんでした.

その子とは大学2年の時の成人式で久しぶりに会って,連絡先を交換していました.

この時は正直,この子に会いたいがために行ってたと思います.

女々しいですね.

その後,何度か会っていたのですが,その頃も精神的にきていたので自分に自身が持てず,「自分なんかが」みたいなクソしょうもないことを考えて,段々と会わなくなりました.

そのことを今更になって後悔したようです.

後悔するなら,当たって砕けようということだと思います.

捨て身の一撃です.

久しぶりにLINEで連絡を取りました.

ここもクソしょうもなさが出てるんですが,実際に合わずにLINEで自分の状況や今の気持ちをぶつけました.

案の定,お相手がいたようでした.

分かってはいましたが,辛かったです.

でも,清々しさがありました.

よし,VR機器とVR彼女を買うためのお金を貯めようと気持ちを切り替えました.

その数日後,彼女から連絡がありました.

「今は会えないけど,ゆうたろう(私)が会いたいなら,そのための準備をする.」という内容でした.

つまり,私に会うために今付き合ってる人と別れるということです.

思いもよらない展開にビビりました.

嬉しかったです.

その反面,いいのか?という感情も湧きました.

自分が一番したくないことでした.

人から人の幸せを奪うことですから.

女々しく,迷いました.

(だから,DTなんだよ.)

でも,これが最後のチャンスだと思い,自分だけのために「会いたい」と返事しました.

初めてだったと思います.

本当の意味で「自分ためだけに決断する」ということは.

会いました.

食事をして,公園に行って,告白しました.

(公園っていつの時代だよ)

人生の中でも一番緊張してました.

自分の本当の思いをぶつけました.

ここまで自分の考えを曝け出したのは初めてだったと思います.

「おk」をもらいました.

人生で初めて三次元の彼女ができました.

嬉しかったです.

本当の意味で自分を認めてもらったような感覚でした.

自分が嫌いな自分を好きと言ってもらえたんです.

しかも,小さい頃からずっと両思いだったようです.

(漫画か?)

この時,彼女のために生きていこうと決心しました.

やばいやつですね.

やばいやつだから適応障害になるんでしょうね.

社会不適合者です.

ある日,その思いを彼女にぶつけました.

(重過ぎでしょ.)

「僕は君に救われたから,君のために生きたい」

漫画のイケメン主人公しか言ってはいけないワードベスト5には入ってると思います.

彼女は嬉しいと言ってくれました.

それと同時に「でも,自分の好きなように生きて欲しい」と言われました.

これには困りました.

彼女のために生きたいけど,彼女は私が好きなように生きることを望んでいるのです.

生きることを辞めようとした人間には酷な話です.

でも,彼女のために色々しました.

研究,仮想通貨,FX,起業のアイデア出し,東京武者修行のためインターンに応募しまくる,研究室の先輩に会いに行くなどなど.

ここまで,自分で動いたのは初めてだと思います.

でも,しっくり来るものはなかったです.

ある時,同じ研究室にいた子がエンジニアサークルを設立したことを知りました.

そういえば,私が情報工学に進んだのはプログラミングで何か作りたかったからだと思い出しました.

とりあえず,頼んで入れてもらいました.

この時,ProgateやUdemyをやってました.

Web系に強かった子が多かったので,私もとりあえずWeb系に進んでみました.

2018年3月からは京都のベンチャーインターンをさせてもらいました.

奇跡だったと思います.

情報工学ですが,開発は未経験だったので.

ありがたく,開発について学ばせてもらいました.

ただ,Web系の文化は好きだったのですが,これでずっとやっていくのは疑問が湧きました.

何か作ろうとした時に何にもアイデアが湧かなかったのです.

思い浮かんだとしても,しょうもないありふれたものばかりでした.

この時に一度自分を振り返りました.

自分がやってきたことを.

その時,自分が一番時間とお金を費やしたものはゲームだったことに気づきました.

ゲームを作ってみることにしました.

すると,アイデアがどんどん出てきました.

これだ!と思いました.

昔から付き合いのあるゲーム制作に興味がありそうな2人を誘いました.

それから,作り始めて,2018年11月4日に秋葉原で開催されたデジゲー博に参加しました.

プロトタイプとデモ映像だけでしたが,こんな体験は初めてでした.

 

今は絶賛就活中です.

ゲームの歴史に残るゲームを作りたいな.

トップダウン的な勉強とボトムアップ的な勉強

初めての投稿として,自分の勉強に対する考え方を発信していきたいと思います.

人それぞれ考え方があると思うので,一つの意見として捉えていただければ幸いです.

 

結論としては,

ものづくりと読書や授業は満遍なくこなしましょう!

ということです.

では,一つずつ説明していきます.

 

トップダウン的な勉強

小難しい言葉を使っていますが,要するに開発やものづくりのことです.

この勉強法はおおよそ次のような過程で進めていくことが多いでしょう.

 

  1. 作りたいものを見つける.
  2. 作りたいものに必要そうな技術をググる
  3. 実際に必要な技術をググる
  4. 必要最低限の技術だけ身につけていく.

 

自分の作りたいもののために勉強していく方法です.

モチベーションが高く勉強ができるのが利点と言えるでしょう.

 

ボトムアップ的な勉強

こちらは学校の授業や読書などのことです.

この勉強法はおおよそ次のような過程で進めていくことが多いでしょう.

 

  1. 予習する.
  2. 人から教えてもらう.
  3. 復習する.
  4. 勉強した知識から派生した知識を学んでいく.

 

人からあらゆる知識を教えてもらう勉強方法です.

体系的に研ぎ澄まされた知識を勉強できるのが利点でしょう.

 

それぞれのデメリット

ここではそれぞれのデメリットについて説明していきます.

 

トップダウン的な勉強

モチベーションが高く続けられ,今流行っている勉強方法だと思います.

では,そのデメリットは何か?

 

1番のデメリットは,

見逃してしまう知識がある

これに尽きると思います.

 

今だとRuby on Railsを使ってWebサービスを作る方が多いでしょう.

フルスタックフレームワークで慣れてしまえば,色んなWebサービスが簡単に作れるのがメリットでしょう.

 

ただし,簡単に作れるのはフレームワークが色んなことを裏でしてくれているからです.

私が真っ先に思いついたのはセキュリティに関することです.

有名な攻撃方法にXSSがあります.

Railsなどのフレームワークは仕様でエスケープ処理をしてくれるでしょう.

 

では,規模が大きくなってきて,他の生の言語に切り替えたくなった時はどうでしょうか.

その時に自分でエスケープ処理を組み込めるでしょうか?

知らなければ無理でしょう.

調べる機会があれば良いですが,誰もがその機会に恵まれてるとは限りません.

 

そんなことはないだろうと思う方がいるかもしれませんが,それはあなたが恵まれた環境にいるということです.

知らなければ,何もできないのです.

 

ボトムアップ的な勉強

大抵の皆さんが大嫌いな勉強方法でしょう.

私も嫌いでした.

 

デメリットはいうまでもなく

モチベーションを保つのがしんどい

これでしょう.

 

モチベーションは人間が物事を続けるために最も大切なものです.

楽しさが人間の生きる理由でもあると私は考えています.

 

「できる」ということは人間にとって,とても楽しいことです.

しかし,ほとんどの人がどこかでつまづくでしょう.

「できない」がどんどん降り積もるとイヤになってくるのも当然です.

 

「できない」の中核にあるものはおそらく「繋がらない」ということだと考えています.

そして,こう考えるでしょう.

これ勉強してなんの意味があるの?

大抵の人は考えたことがあるでしょう.

 

私は理系なので数学に焦点を当てますが,数学はありとあらゆるところで使われています.

最も身近なものにスマホがあるでしょう.

スマホは最新技術の結晶です.

様々な技術で数学が使われています.

 

ですが,「繋がらない」と分からないです.

 

どちらの勉強方法がいいのか

では,どうすればいいのか?

どうやって勉強していけばいいのか?

 

どちらも満遍なくやっていきましょう

 

これら二つの勉強方法は互いに自身のデメリットを補填していることに気づいたでしょうか?

 

トップダウン的な勉強は

  • モチベーションを保つのが楽
  • 見逃す知識がある

 

ボトムアップ的な勉強は

  • モチベーションを保つのが難しい
  • 幅広い知識を体系的に学べる

 

トップダウン的な勉強では見逃す知識をボトムアップ的な勉強で補う.

ボトムアップ的な勉強での「繋がらない」をトップダウン的な勉強と紐づけることで「繋げる」.

 

これが私の考えるベストな勉強方法です.

 

経験談

ここからは私の経験に基づいて話していきます.

 

私は現在Unityを用いてゲーム作りをしています.

とりあえず,設計も何もせずに開発に取り掛かりました.

というよりも,設計自体したこともなく,必要性も感じませんでした.

 

作ってみよう!

ただそれだけで作り始めました.

 

最初は何も問題が起きませんでした.

Unityは誰でも簡単にゲームが作れるように設計されているので,当然なのかもしれません.

 

しかし,コードが大きくなるにつれて辛くなってきました.

どこでどの処理を書いたか分からなくなってきたのです.

 

更にどこかを書き換えたら,どこかに影響が出るのではとビクビクして,書き換えることに抵抗がありました.

 

その時,大学で少し習ったソフトウェアアーキテクチャについて思い出しました.

依存性がなんちゃらって言ってたなという感じです.

 

とりあえず,ソフトウェアアーキテクチャについて調べ,オブジェクト指向について調べ,デザインパターンについて調べ…

こんな感じに数珠繋ぎ状態で調べていきました.

 

そして,ゲームの設計について書かれている資料を見つけ,とりあえず少しだけでも組み込んでみようと頑張りました.

私が見つけたのはUniRxを用いた,MVP設計とstrategyパターンなどのデザインパターンでした.

 

取り入れてみると,一つのクラスのコード量が大幅に減り,可読性も上がりました.

依存関係も解消され,コードの書き換えにビクビクしなくなりました.

 

やったぜ

 

これができたのは私が大学で少しでも設計に関する知識を学んでいたからです.

これがボトムアップ的な勉強の強みです.

 

途中にも書きましたが,

知らなければ,何もできないのです.