WEB系に転職して1ヶ月

SI企業から事業会社(WEB系企業)に転職して1ヶ月半が経ちました。

そこで1ヶ月半経って感じたSI企業との違い、現職の課題、個人としての1ヶ月半の反省・今後に向けてと言ったところを今後の自分のためにまとめておきたいと思います。

入社して感じたこと

転職を考えた理由

私は20代後半なのですが、社会人になってからずっとSI企業に所属していました。
これまではシステムをもっとこうした方が利用者にとって使いやすいのでは?と思ったり、この実装がイケてないからリファクタリングしよ
うとか思って行動しても、エンドユーザーの都合(予算など)や逆にSI企業側として採算が合わないから対応出来ないなど多々ありました。
また、技術的にもSI企業にいる方々にとっては重要なものではなく、プログラミングはオフショアなどが行うもの(悪く言えば下っ端?がやるもの)、うちの会社は全員PMを目指すべきみたいな考え方が一般的になっていました。
※もちろん全てのSI企業がそうだとは思っていませんが、私の周りはそういう会社ばかりでした。

私も以前の会社に入社したばかりの頃は「PMを目指すべき」「コーディングは道具であり、要件定義などを中心にやりたい」と考えていました。
実際にコーディングをオフショアに依頼して、自分はプロジェクトを推進したり要件定義だけを中心に行うということを続けていました。
ですが、コーディングのバグが多かったり可読性が低かったりして、開発に時間がかかったり手戻りが発生したりということがあり、コーディングの重要性を認識するようになったのですが、周りの人はコーディングに興味がないので、改善しようにも出来ないという状況になりました。

そういったことから、自分で企画からコーディングまでしていける環境つまりWeb系企業へ転職しようと決意したことが今回の転職のきっかけになります。

入社した会社について

入社した会社は事業会社です。
一般の方が利用するサービスだけでなく、toB向けもある会社になります。(というかBtoBtoCという事業)
私はtoC向けのサービスを希望していたので、toCサービスを行うことになりました。

勤務時間はIT業界では珍しく9:00~17:20で、残業もあまりないので毎日早く帰って家でもプログラミングする時間が増えました。
エンジニアは朝が弱いとよく言いますが、私にとっては早く帰れることの方が嬉しく、今は業後も充実した日々を送っています。

その他、書籍を会社が購入してくれたり、リモートワークが出来るようになってきたりと以前までの会社であれば考えられない良い環境です。

肝心の開発環境になりますが、以下のような環境になります。

言語 Java8(APIサーバ)、PHP5.6(WEBサーバ)
フレームワーク Seasar2、Zend1、jQuery、Angular
DB OraclemySQL
インフラ AWS
コード管理 git
その他 ApacheTomcat、JIRA、Hipchat、

私は現在はサーバサイド(APIサーバ)をメインで対応しています。

私と同じtoC向けのシステムを作成している人は、40人くらいいるのでは?と思っています。
外部委託や他社からエンジニアが常駐していたりします。なので社員よりも外部の会社の人が多いです。

入社して感じた課題

この1ヶ月の仕事内容ですが、最初の2週間程度はほぼ仕事が振られない状態でしたので、既存のソースをなるべく理解するようにしていました。
そのあとは徐々に仕事が増えてきて、既存コードの修正(軽微なもの)やバグ対応、最近では新規にAPIを作成したりなどをしていました。

まだ1ヶ月半で詳細まで理解出来ていない部分もありますが、この会社のシステム部分に感じた課題をまとめておこうと思います。

技術面の課題

フレームワークを使えていない

現在はSeasar2を利用しているのですが、フレームワークの使い方を間違っているようなロジックが見受けられました。
例えば全てのAPIが同一のURLになっていて、リクエストパラメータ内にSERVICE=(対象サービス)を設定することで、APIを変化させるというような仕様になっています。
このようなロジックになっていることで、例えば全サービスで利用する1つのFormを全員でメンテナンスしていくというような状態となり、巨大なロジックが出来上がっていて、可読性が大変低い、同時に開発する人とコンフリクトが発生する可能性が高い(かつ同一名称をつけたら大変なことに・・・)みたいな状態になっています。
ちなみに、全てのAPIがGETメソッドでもPOSTメソッドでも動くようなイマイチ仕様になっています。

まだログの取得などもAOPを利用すれば簡単に出来てかつ、それぞれの業務ロジックに無駄な処理を書かなくて良いと思うのですが、それも利用できていないなどの問題もあります。

トランザクションの操作についても考えられていない状態(なので途中でExceptionを起こしたら不整合になる)であったり、考えられていてもトランザクションの設定位置がLogicパッケージに対して行われていたりするので、1Actionの中で複数のLogicを読んでいたら破綻する状態となっています。

・責務が意識されていない

例えばMVCが意識できておらず、ViewにModel依存のロジックがガリガリ書かれている、Modelで返却する値(XML)を組み立てている。
SQLにIFがめっちゃ書かれている(S2DAOなのでSQLファイル内でIFを使えます)、SQLでなんでもやろうとする。
リクエストパラメータの入力チェックをしていないので、Logic内で無理やり「try catch」。
Webサーバ側にロジックを書きすぎていて二重に実装している。

といったところが気になっています。

MVCが意識できていないということは、改修する際にどこを修正すれば良いのかの判断が難しくなりバグや調査時間がかかる原因になると考えています。

SQL内にIF文が多く書かれていると、単体テストが難しくなる(めんどくさい)ので、バグの検知が難しくなります。
また、SQLでなんでもやろうとしているので超長いSQLが出来上がります。周りの人もですが、書いた人本人も1ヶ月後には絶対に読めない状態になっていると思います。

リクエストパラメータのチェックというのは本来であれば処理の最初にすべきだと思います。
最初にすることで後続で想定外のことが起きにくいですし、処理も速く終わらせることが出来ます。
しかしリクエストパラメータのチェックをあまりしていないため、Logic側でエラー処理をしていて(おそらくテスト段階で困ったから無理やりつけた)、しかもそれをLogic内で握りつぶしていて、本当にロジックの問題などで起こるExceptionが発生した際にもHTTPステータス200応答かつスタックトレースとかも出力しないため、バグがあるのかどうかもわからない状態になっています。

現在のシステムはWebサーバとAPサーバが分かれていて、Webサーバ側はPHP・Zendによりフロント側(画面系)の処理を、APサーバはJavaSeasar2でDBに接続できるようになっておりビジネスロジックが書かれています。APサーバでAPIを用意してWebサーバがそれを呼び出すというような状態になっています。
ですが、PHP側にもAPIを呼び出すためのAPI的なもの(Facadeと読んでいる)が用意されていて、JavaScript側ではPHPAPIを呼び出して、PHPAPI内でAPサーバのAPIを呼び出すというような仕組みとなっています。
しかもPHP側のAPIにもAPサーバにあるものと同じようなロジックを入れていることで二重にロジックが書かれていたり、そもそもWEBサーバとAPサーバが分かれているのってそれぞれに役割分担をさせて負荷を軽減することだと思うのですが、Web側にゴリゴリロジックを書いているので逆に負担かかってない?って状態になっています。

スーパークラスがなんでもやっている

API(Service層)では共通のAPIを親クラスに持っています。
そしてその親クラスにはいわゆる共通系ロジックが書かれている状態です。
なので、各APIからその親クラスのメソッドを呼び出したり、逆に親クラス側のメソッドから子クラスでオーバーライドしたメソッドを呼び出していたりしていわゆるスパゲッティコード状態になっています。
コードを読むのが本当に辛いです。

Template Methodパターンになってはいるのですが、具体的な業務ロジックまでスーパークラスガリガリ直接書いている状態なので、それを利用していないサブクラス側でも毎回それを呼び出して無駄になっているし、可読性は低いしという状況です。

よく言われていることですが、継承はAisBの関係の時に利用すべきであって、そうでない場合(無駄なロジックが入っている)にはコンポジションを使いましょう。

その他技術的に課題に感じる部分は色々ありますが、大きくこんなところです。
つまり技術的課題がたくさんかつ修正も難しい状態になっています。

人材/体制的な課題

・ベンダー依存

今でこそ社員がコードを書いていたりするんですが、昔は外部に委託していたみたいで、今なお社員よりも外部ベンダーが多い状況です。
なのでベンダー依存が高いです。
依存していることの何が悪いかという話になりますが、古い方々が多いので先ほどあげたような技術課題が解消されないまま残っている原因になっているのでは?と思っています。
しかも可読性が低いので、古くからいる人がいなくなるとどうすれば良いのかわからないロジックも多いので、辞めてしまうリスクも高いです。

その他自分の会社のシステムではないので、技術課題を感じても何も出来ないというのもベンダー側としてはあるのかもしれません。(私も転職前はそうでした。声には出すけど何も動き出さない)

ただこの課題は上の方も認識しているみたいで、最近は私含めて転職者を多く受け入れて内製化を進めようとしています。

・SEとプログラマという役割分担

SIにはよくある構造だと思うのですが、この現場もSE(要件定義とかやる人)とプログラマで役割が分かれています。
が、私としてはこの構造は微妙かなと思っていて、プログラマも全体像を理解して開発しないと良いシステムは作れないと思っています。

今はプログラマはSEに言われたことをそのまま開発するような役割分担になっていますが、そうではなく最初からプログラマが積極的に関わって一緒に考えていくような仕組み作りをしていければと思っています。

・開発着手まで

開発着手までは企画→見積もり→開発という流れになっています。
この見積もりの部分が問題だと思っていて、開発リーダー的な人(古くからいるベンダー)が影響調査してどう実装するか(具体的なコードまで)も決めて見積もるという流れになっています。
プログラマはその内容を見て開発するという流れです。

特に問題だと思うのは、影響調査して実装も決めちゃうならもうそこで開発すれば良くない?というスピード感です。
簡単な修正であっても見積もりしてから開発になるので、無駄が多いです。

というかどう実装するかまで決めるならプログラマはいらないという話ですね。

・人材のスキル面

今回の転職ではWeb系企業をいくつか受けたのですが、どの会社もスキルが高い方が多い印象でやはりSIとは違うなぁという印象だったのですが、今の会社に限って言えばスキルはそこまで高くないかもしれません。
Web系は家でも勉強しているのが当たり前だと思っていたのですが、そういう方はあまり多くなく、私が勉強している方という状況です。
今回の転職で優秀な方と働きたかったのでそこはすごく残念ですが、選んだのは私ですし、逆にいえば私が色々変えていけると思っているのでそこは諦めます。

が、今のレガシーなシステムを改善していくには優秀な方が必要だと思うので、アプリケーション側に詳しい方が増えるといいなぁと思います。
幸い上の方はプログラミングに対して前向きな方が多いので(SIのようにマネージャーになるべきみたいな考え方は少ないかも)、そこは改善しやすいのかなと思います。
ただ中途採用で優秀な方を雇うには給与が低いので難しい面があるかもしれません。

個人的にやりたいこと(目標)

上記のような課題を感じた中で個人的に今後やりたいこと・それまでに身につけたいことをまとめていこうと思います。

仕事面

・影響力の向上

これは他のやりたいことを実現するためにマストで取り組まないといけないことだと思っています。
今の状態だと来たばかりで何が出来るのかも分からないのに口だけ課題を言い続ける若手という扱いになってしまうので、早急に「この人は出来る」「この人じゃないとダメだ」「辞められると困る」という状態に持っていかなきゃいけないです。

しかも自分の成長やモチベーションを考えるとなるべく早急に色々と変えていきたいので、そのためには半年以内にはそういった状態に持っていこうと思います。

そのためには、技術力の証明、問題解決力を見せる、人間的な信頼関係を構築、仕事に対しての前向きさを見せる。などをしていかないといけないです。
特に技術力についてが難しいなと思っていて、単純に案件をこなすだけだとそこを理解してもらうのは難しいと思うので、仕事では人より早くかつバグが少ないコードを書いていかないといけないし、それだけだと短期間で信頼してもらうには難しいのでQiitaなどで個人の名前で色々と記事を書いて見せつけていくなどをしていかないとと思っています。

・既存のコード理解

先ほどから言っているように既存のコードは可読性がかなり低くて読むのが辛い状況なのですが、それでもこれから修正していくには理解しないとどうしようもないと思うので、重要なロジックは読んで理解しようと思っています。
できれば入社して半年(9月頃まで)には全体像を理解しておきたいなと考えています。

・テストコードの定着

今は一切テストコードが書いていない状況です。(それはつまり単体テストが出来ていない状態でcurlAPIを叩いているということになります)
今後リファクタリングをしていきたいと考えているのですが、そのためにはテストコードによってデグレが発生しないようにしてからだと思うので、テストコードを書くという習慣を定着させていきたいと思っています。

今まで書いていなかったのを書くということなので、最初はコーディングスピードが落ちると思うのですが、そこだけを見て却下されないように説得できる材料を増やしていかないとなと思います。
まずは私がテストコードを書いて、スピードが変わらないことを証明していかないとなと・・・

・テックリードしていきたい

最後にこれは曖昧な表現かつ長期的な目標になってしまうのですが、テックリードしていけるようになりたいなと思っています。
今の会社で技術に強い人がいないので、抜け出た存在になっていこうと思っています。

その上で社内の開発スピードをあげたり、新しいものを取り入れて業界の中で競い合っていける技術力を社内に広めたいです。
あとは社外的な部分でも、今の会社に優秀なエンジニアが入社したいと思えるように何か還元できればなと思います。

正直現時点での想いなので、いつまでにとかは考えていないですし、今後は変わるかもしれませんが、目標として持って今後定期的に振り返っていこうと思います。

個人的な目標

その他個人的に勉強していきたいところをまとめておきます。

プログラミング

当面はひたすらにJavaを勉強していこうと思ってます。
今回の転職活動で勉強不足を理解出来たので、1年後には社外でも評価されるようなエンジニアになっていたいと思います。
そのために必要だと思うのが以下の要素です。

・Effective Java

本を読んで実際に利用して、効果的なプログラミング方法を理解していきたいと思っています。

[商品価格に関しましては、リンクが作成された時点と現時点で情報が変更されている場合がございます。]

Effective Java/ジョシュア・ブロック/柴田芳樹
価格:4320円(税込、送料無料) (2019/4/20時点)


デザインパターン

こちらもデザインパターン本を読んで、現在のコーディングを修正するのに活用して覚えていこうと思います。
エンジニアとして理解しておかないといけないものなので、早期に学びます。


OSS活動に参加

何かしらのOSS活動に参加したいと思っています。
今、いくつかのOSSライブラリのコードを読むことが増えてきたのですが、やはり綺麗なわかりやすいコードになっているので、それを真似しながら成長していきたいと思います。

フレームワーク理解

spring bootや業務で利用しているSeasar2などのフレームワークについてコードを読んで理解したいと思っています。
転職活動でもフレームワークの違いなどについて聞かれたものの答えられなかったので、1年後にはフレームワークの特徴など、深いレベルで会話できるようになりたいなと思います。

プログラミング以外

AWS

業務で利用しているのですが、ほぼ理解できていないので、勉強しなきゃなぁと思っています。
AWSのyoutubeセミナーが良いと聞いたので、通勤時間に見ようと思っています。

・フロントエンド

私はサーバーサイドをやっていきたいと思っているので、フロントエンドをどこまで勉強すべきかが悩ましいところですが、Javascriptを普通に触れるくらいと出来れば、React、Vueあたりに触れておきたいと思っています。

・DB

あまりDBの細部まで詳しくはない状況なので、Oracle Silverレベルまでは理解しておかないとなぁと思ってます。(資格を取るかは別だけど)
あとは普段から統計情報を見る習慣がつけばなと思います。

・その他

docker、gRPC、Swaggerなど最近よく聞くものについて勉強していかないとなと思ってます。
業務では利用しないので、プライベートで勉強しつつ良いものを展開していく方法でいいかなと思ってます。

以上です。
今後は定期的に振り返りを行い、成長度合いを確認するようにしたいと思います。