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割ぐらいしか理解できてないです.ですが,理解してシステムを作っていくことができれば,いい仕事ができるはずと信じて勉強してます.

まとめ

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

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

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

あとがき

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

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