1年半近く関わったプロジェクトが完了したため総括する。

はじめに

一年間半近く関わったプロジェクトが完了間近になっています。要件定義を経てドキュメントの作成、実装、単体テスト結合テスト、総合テスト、受け入れテストと完了し、バグはなく、要求は満たせており、プロジェクトとしては成功という事になっています。顧客も概ね納得頂いているようです。リリースはまだですが、バグ自体は環境要因以外ではおそらく出ないでしょう。品質*1は問題ないというのが上司の主張です。ですが、私はハッキリと大失敗したと考えています。顧客の大切なお金を無駄にしてしまいました。設計はガタガタで、実装は酷い有様です。今は問題が生じていないですが、きっと保守開発のスピードが大きく低下し、お金をかけた割にシステム利用のフィードバックが改善されずに、失敗プロジェクトとして受け取られるようになってしまうと思います。今後の取引はなくなるでしょう。本当に悔しい気持ちで、自分が恥ずかしくて仕方ないです。二度と同じような失敗プロジェクトに導かないために総括します。

背景

私は経験3年目のITエンジニアです。一年ほど雑用みたいな仕事に関与したあと、初めて今回のような要件定義から行うプロジェクトに参加しました。プロジェクトの目的としては古くなったUI層を刷新しつつ、新規機能を複数追加するプロジェクトです。顧客側発注チームはITベンダに丸投げをしていて自社システムのことはあまり分かっていない様子でした。こうしたいというデザインイメージはあったため、それを何とかして引き出して頂き、追加したい機能についても伺っていました。私の所属する受注チームは顧客のシステムの保守運用を担当しているITベンダです。保守運用がメインですので、開発についてはほぼ素人集団です。他にデザインを担当するデザインベンダーが存在しています。このような体制でプロジェクトが進んでいました。

問題点

要件定義結果として今あるシステムのHTMLを書き換えてviewを刷新するということになりました。 しかし、今になって思うとこれは顧客が本当にやりたかったこととは思えません。 我々がやるべきだったことは、現在のサーバサイドでJSPコンパイルしてHTMLを返す昔ながらのシステムから、バックエンドとUI層を切り離して、モバイルでもWEBブラウザでも利用できるようにすること、さしあたってはWEBフロントエンドを現代的なWEBアプリケーションとしてフロントエンドフレーワークを使用して作り変えることだったはずです。そのためにWEB APIによってJSONを返すようにバックエンドをリファクタリングするチームとWEBフロントエンドをゼロから構築するチームに二分割してプロジェクトを進めるべきでした。*2 これによって、顧客は今後5年はそのWEBアプリケーションを利用しつつモバイルAPPを作成して両面から集客してビジネスを進めることが出来たはずです。いま、この時点でそのプロジェクトを進めるべきだったはずです。そうでなければUIの古臭さによって競合に差を付けられてしまいます。我々が作ったjQueryを使用した昔ながらのviewではもはや競合には勝てません。

次の問題点として、今のシステムにはテストコードがありません。元々は存在していたようなのですが、保守開発を続けるうちに壊れてしまい、無視されて廃棄されたようです。悲しいですね。我々はテストコードを書き直すプロジェクトを行うべきでした。何度も説得したのですが無駄でした。

この要件定義を経て良くわからないデザインベンダーが作り上げたHTMLとjQueryを使用してただただHTMLを書き換えるプロジェクトが進行しました。しかし、そんな作業をしていてももはやソフトウェアの根本的な価値を増進することにはなりません。この時点でプロジェクトは失敗していました。

プロジェクト結果

その後、良くわからない設計ドキュメントというエクセル資料を大量に作成する作業で顧客の資金を無駄にし、実装はバグが無いものの可読性の低い修正困難なコードが量産され*3、結局テストコードは書くことが出来ませんでした。わざわざ書きませんがプロジェクトの大部分は信じられないような無駄な作業が大半を占めており、指摘しても聞き入れられませんでした。システム自体はリリース判定を超えてリリースすることが決まっています。しかし、果たしてこれからシステムを保守運用していくことが可能なのでしょうか。システム自体は動くはずですが、機能追加などの速度は一気に落ちてしまうはずです。viewはデザインは新しくなったものの見かけだけで、利用者のUXの改善につながるとは到底思えません。

何故こうなってしまったのか

何故こうなってしまったのでしょうか。発注側、受注側ともに私含めて素人ばかりだったからこうなってしまったのだと思います。顧客チームはシステムのことを丸投げしていたせいでまともに仕様すら把握していない。受注側はソフトウェア設計についてまるで知らず、その場しのぎの対応しかできない。ソフトウェア開発が専門職集団による知識集約型の仕事だということをあまりにも理解していないから、こうなってしまうのでしょう。私はもうこんな仕事はしたくありません。顧客の資金を有効に活用し、ソフトウェアの価値を高めていく仕事をしたいです。もう本当に嫌になってしまいました。

これからどうするか

今回のことを経て専門知識がなければソフトウェア開発を受注してはいけないと強く痛感しました。なによりもソフトウェア設計の重要性が身にしみてわかりました。 上に挙げた問題点もClean Architectureでviewとビジネスロジック疎結合にすることの重要性を学んだから気づけたことです。entityとユースケースを保護しつつフレームワークやUI層はいつでも切り替え可能な設計にするべきでした。ソフトウェアの設計自体を大きく変更する視点が必要だったのです。リッチなウェブアプリケーションが増えるにつれて古臭いjQueryを使用したシステムはなんだか見劣りすると思われてビジネスの足かせになってしまうでしょう。他にもウォーターフォールの問題点や、コードの可読性、テストコードの重要性についてなど、多くの反面教師となる事象に気づきました。結局の所問題はすべて学ぶこととソフトウェアを良くしていくことに対する情熱がかけているから発生しているのです。私は知らないことが多すぎてめまいがするほどですが、良いソフトウェアを作成して顧客に貢献するためには、これから死ぬほど学ばなければいけません。今回のプロジェクトはそんなことを気づかせてくれました。

楽しかったこと

愚痴っぽくなってしまいましたが、楽しかったこともあります。 自分が作成した機能やバッチが無事動いて出力が表示される時はとても楽しいです。自分の実装した共通機能がチームメンバーに利用されるのは嬉しいです。 意味不明なバグを解決した時は自分で自分を褒めたいような気分になります。他メンバーが解決できないバグを自分が直せた時などは平静を装いつつも内心は「おっしゃあ!」と思っています。 もっと、そんな楽しいことをたくさんしていきたいです。

*1:バグがなく、要求を満たせていること

*2:多分我々のチームでは出来ないでしょう…。でも、それを提案するべきだったというのは間違いないです

*3:ちなみに派遣で来たメンバーが残したコードはバグまみれでした

ソフトウェアの設計を習得するケツイ。

最近、ただ動くソフトウェアを作るのではなく、動くソフトウェアを、後々改修しやすいソフトウェアを、素早く作ることが重要だと思うようになった。
これは、現職での経験が影響している。現職では汗水たらして大勢の人間を投下してソフトウェアを作っているのだが、これがお金と時間をかけた割に出来が悪く、どうしてこうなってしまったのかをよく考えていた。
結論としては設計ということをしていないことと、自動コードを書いていないことに尽きると考えている。
現職では設計ということをしていない。一応設計というフェーズはあるのだが、エクセルに自然言語でコードと一対一になる設計書という資料を作成し、設計書として顧客に納品するためのフェーズを指している。
これは設計ではないでしょう。確かに、コードとは別に仕様を表すドキュメントは必要だとは思うんですが、それはJavaDocなどで自動生成したり、あるいはテストコードを仕様書代わりにすれば良いんじゃないのという疑問が尽きない。それでなくとも、エクセルに実装と一致するレベルの粒度で書くのはどう考えてもおかしくないか。話がそれた。このフェーズで作られた資料はあくまで自然言語で書かれた実装であって、設計資料ではないわけである。設計というのは、仕様を抽象化して、モデルに落とし込み、そのモデルの関連を図で表現してドキュメントに落とし込む行為じゃないんでしょうか。そしてそのドキュメントをもとに実装に落とし込むのであれば、私としては全然違和感がないわけである。しかし、現実としては設計は行わずに、既存のコードベースをもとにして実装をでっち上げ、コピペで格闘して行くわけである。実装するには一度自然言語でエクセルのフォーマットに沿うように書かないと行けないわけであるから、そのエクセルのフォーマットや自然言語で書くときのドキュメントの書きやすさに実装が影響されるわけだ。これなら設計フェーズいらないんじゃないの。まぁ、設計フェーズは顧客と合意して契約に則って行い、納品物として提出しなければいけないので、仕方がないことである。仕事はこうして効率などは無視して顧客のために実行される。
話を戻すと、設計を(ここでは抽象化とモデリングの意味の設計である)適切に行うことができれば、それぞれのモジュールが疎結合になり、テスト用にモジュールを切り替えたりしてテストコードが実装しやすくなる。これこそが設計の目的でしょう。テストコードを実装するためにはどうすれば良いだろうかと頭を悩ますことがなければ、もはや設計などする必要はなくなる。DBに密接に結合して、関数は巨大になり、クラスの責務は滅茶苦茶だとしても、テストコードを書くことや後々の保守性を気にしないのであれば、エクセルに自然言語で実装して設計書ですと言い張ったところで痛くも痒くもないわけだ。 そういう仕事は私はしたくない。動くソフトウェアを、後々改修しやすいソフトウェアを、素早く顧客に提供したいと思っている。だからこそ設計を学び、テストコードを書くために努力をしなければいけないのだ。

あ~疲れる。でも、それが本来のソフトウェアエンジニアのはずだ。

プログラミングスクールで勉強している。

タイトルの通り、2月初旬ごろからフィヨルドブートキャンプというプログラミングスクールで勉強しています。 記録上は累計200時間ほど勉強しています。少ないですね。記録をつけていない日があったり、割と時間は適当に計測しているので実際のところは合計350時間ほど費やしているでしょうか。だいぶ勉強が進んできて色々出来るようになってきたので一旦の振り返りとしてこの記事を書いてみます。別にこの記事で報酬を貰ったりは一切していないので、完全に個人の感想です。 bootcamp.fjord.jp

自己紹介

W大学の文系学部を卒業後、2年と少しSierで働いている26歳の男です。一応ITエンジニアという分類にはなります。

経緯

文系の大学を卒業した後Sierに入社しました。そこは、残念ですが私が期待していたエンジニアリングをやっている会社ではなかったです。悪い会社だとは言いませんが、価値観が合いませんでした。この会社でエンジニアとしての能力を身に着けるのは厳しいかなーと思い、 独学で勉強して転職しようと思ってました。 しかし、独学で勉強していると結構困ることがあります。

  • カリキュラムがないので好き勝手気になることを勉強しがち
  • 期限がないのでダラダラ勉強してしまう
  • フィードバックがないので学んだことのアウトプットが正しいかわからない

以上が大きな問題になります。

そんなこんなで好き勝手ダラダラ勉強して時間が経つのに焦りを覚えていました。

ある時Vさんというソフトウェア開発会社の経営者さんがこんなtweetをしていました。

この発言については一理あると思いました。この人が言うなら信用できそうだなと思い、フィヨルドブートキャンプで勉強してみることを決めました。 (いろいろあって2021年2月からになりました)

感想

結論を先に言っておきますが、フィヨルドブートキャンプで勉強を始めたのは非常にいい決定でした。

どう変わったか

フィヨルドブートキャンプで学習を始める前の私はだいたいこんな感じでした。 だいぶ雑ですが、分かってない部分を中心に書いてます。分かってることは書いてません。

  • Javaで既存システムの改修はできる。新規にモジュールを作ると手続き型の酷いコードを書き始める。
  • 基本的なJavaScriptは書ける。クラスは使わず、非同期処理も適切に書けない。
  • DB設計は正規化していない滅茶苦茶なものを作る。
  • Linuxについてはcd, ls, pwdくらいしかわからない。
  • テストコードの書き方がわかってない。書いたことがない。
  • 一般的なweb application frameworkにあまり触れたことがなく、機能としてどのようなものが存在するか知らない。

いま時点ではこんな感じでしょうか。

  • 適切な抽象化をしてクラス分割をした上でRubyのコードが書ける。結果的にJavaでもオブジェクト指向に則って書けるようになった。
  • クラスに分割してオブジェクト指向に則った形でJavaScriptを書ける。async/awaitとPromiseを使って非同期処理に対して適切に対処ができる。
  • 適切に正規化をした上でDB設計を行うことができる。
  • Linuxパーミッション周りが分かっており、他にもsshで接続した上で必要なソフトウェアをインストールし、環境構築が出来る。
  • TDDの方法論について知っている、どのようなテストコードを書くことで要件を満たしていることのチェックが出来るか考えられる。適切にテストコードを実装できる。
  • Ruby on Railsにどのような機能が存在しているか知っており、要件に対してFrameworkの機能を使用することで実装が出来るか調査ができる。

他にも元々うっすら知っていて知識として強化された事柄は数え切れないほどあります。

他に技術と関係ない部分としては、フィヨルドブートキャンプでは基本的に勉強した日は日報を書くのですが、 書いていくうちに学んだことをアウトプットとして人にわかりやすく伝えることを意識するようになりました。これは結構大きな変化です。

フィヨルドブートキャンプで学んでいる人たちはプログラミング未経験であっても他の分野で優秀な人なんだろうな、と思わせることがあり、 根拠としては日報に考えをまとめるのが上手な人達が多いです。この点もかなり参考になります。

コードレビューがありがたい

フィヨルドブートキャンプでは皆さん優しくレビューしていただけます。頂いた指摘におかしなことはほとんど無いですし、間違っていたとしても(人間なので当然間違えることはあります)根拠を示せば皆さん納得して頂けます。このコードレビューで自分では気づかない部分で改善される部分が多かったです。

独学で学ぶデメリットは解消されるか

独学では以下のデメリットがあると挙げましたが、全て解消されました。

  • カリキュラムがないので好き勝手気になることを勉強しがち

よく考えられたカリキュラムがあるので、それに則って勉強を進められる。

  • 期限がないのでダラダラ勉強してしまう

明確な期限は無いのですが、他の方がガンガン進められているので、触発されて効率よく勉強するようになりました。

  • フィードバックがないので学んだことのアウトプットが正しいかわからない

アウトプットを確認していただけるので、間違っている場合はちゃんと指摘を得られます。

結論

まぁ、このように色々出来るようになりました。勉強していて楽しいし、真面目に勉強している人は多くて好感を持てるしでかなり良かったです。 あとは、実際に学習に使っているシステムをアジャイルで改善する課題があるのですが、こちらをやってみたいが為に入ったようなものなので、頑張りたいです。(現職はウォーターフォールのため、アジャイルのことは何もわからない)

SierでITエンジニアを始めてから二年で読んだ本

棚卸として書いておく。

Python

大体この本を読んだせいで今ITエンジニアをやっている。

上の本の流れで読んだ。Pythonはもう忘れた。

コーディング

  • これからはじめる プログラミング基礎の基礎

  • Webを支える技術

  • リーダブルコード

  • Code Complete 途中まで

  • 詳説 正規表現

  • プログラミングの基礎

おすすめ。関数型言語の入門に最適。プログラミングをする上での状態遷移やTDDやアルゴリズムやその他いろいろなことを学べる。

セキュリティ

  • 安全なWebアプリケーションのつくり方

Java

DB

  • SQL実践入門

  • すっきりわかるSQL

  • らくらくERDレッスン

  • 達人に学ぶDB設計

JavaScript

React

  • りあクト 1-3

Ruby

テスト

オブジェクト指向

unity

  • unity5入門

Linuxunix

まだまだ読んだはずだがめんどくさくなったので今度更新する。

好きなゲーム

本当に好きなものだけ。記憶を消してまた遊びたいものだけ。 何故書いたかというとouter wildsは本当に素晴らしいということを伝えたいから。

シングルプレイ

マルチプレイ

嫌いなゲーム

  • league of legends

徳丸本 33-001a:シンプルなリクエスト(CORS対応)にて CORS対応ができない

事象

徳丸本 33-001a:シンプルなリクエスト(CORS対応)にて CORS対応ができない

該当HTMLからXMLHttpRequestを行ったとき、

CORS ヘッダー ‘Access-Control-Allow-Origin’ が足りない

というエラーが表示される。

OWASP ZIPには以下のエラーが表示される

f:id:earthminami:20200823162622p:plain

error log

原因

api.example.netへの疎通が取れていないことが原因だった

 

解決策

hostsファイルのtypoを修正して解決

 

 

 

javaでxml parse実行時にjava.net.ConnectionException connection refusedエラーが発生する

事象:

java11にてDocumentBuilderを用いてxmlファイルをparseしようとした際に、

java.net.ConnectionException connection refusedというエラーが発生される。

 

原因:

DocumentBuilderはparse実行時にリモートにあるDTDというXML文書の形式を定義したファイルを読み取りに行く。今回の実行環境では、リモートファイルへのアクセスを遮断されていたため、事象が発生していた。

 

解決策:

以下を参考にし、DocumentBuilderの実行時にリモートDTDを読みに行かないようにインスタンスの定義を変更することで、解決することが出来る。ただし、リモートDTDを読み取ることが出来ないため、parse時に別の問題が発生する可能性がある。

 

https://qiita.com/yoshi389111/items/3d0da72b1f2ccd947052

 

振り返り:

なぜリモートDTDへのアクセスが遮断されていたか不明

リモートDTDへのアクセスが必要な理由が不明

リモートDTDの役割が不明

パース実行時にリモートDTDを読み込まないことによる影響が不明

パース実行時の動作が不明