SE(たぶん)の雑感記

一応SEやっている筆者の思ったことを書き連ねます。会計学もやってたので、両方を生かした記事を書きたいと考えています。 でもテーマが定まってない感がすごい。

はじめてJavaとWeb開発を経験したので感想を書いてみる

私はSEとして働いていますが、これまでほとんどWeb系の開発をやっていませんでした。

一応、Webサービス経由でデータを取得したりするデスクトップアプリは経験ありましたが、Webをやったという感じは一切なかったので…
そんな人間が、Web開発をやってどう感じたか、徒然と書いてみます。

あと、Java初経験でした。

概要

とあるアプリから呼び出すWeb APIを作成する
サーバー側のDB定義等も作成する
管理機能として、いくつかWebページも作成する

言語

Java 8(Play Frameworkを使用)
開発はEclipseで行うが、デバッグ等はPlayで行う

参加の経緯とか

暇だったからという、あんまりな理由です。
まあ、人手不足だったらしいので、ちょうどよかったという背景もあります。

なお、わたくし、当時はJava未経験でした。
やっぱり、暇だったから選ばれたようでした。

一応、Webの知識はざっくりあったものの、Content-TypeとかAcceptとか、HTTPヘッダーにつける項目の意味が分からない程度には素人でした。

どういうときに、レスポンスは何番を返せばよいのかも、よく分かりません。*1

Javaで苦労した点

ブログに散々書いている通り、C#が得意なので、Javaはそれほど違和感なく触れました。

それでも、苦労したので、その点残します。

文字列

もはや定番ですね。誰もが一度は通る道。

public void Search(User user) {
    if(user.Name == "xxx") {
        //何か
    }
}
public void search(User user) {
    if(user.getName() == "xxx") {
        //何か
    }
}

ではダメなんです!!!!

リクエストを投げて、

なぜ動かない…?

と思ったのは一度ではありません。

Javaだとこうなります。

public void search(User user) {
    if(user.getName().equals("xxx")) {
        //何か
    }
}

これでも、オブジェクト指向はしっかり理解しているつもりで、==ではダメな理由はわかる*2のですが、C#の優しさに触れた私は甘えていました…

プロパティ

getter、setterが忌み嫌われる理由が、よく分かりました。

エンティティ等を使うと、どうしても必要になる*3ので、我慢して使っていたのですが、可読性落ちていくのが気に入りませんでした。

リスト

List<int> values = new List<int>();
List<int> values = new ArrayList<int>();

という違いは、まあいいのですが、

int value = values[0];
int value = values.get(0);

あと、Javaでリストにint入れると、ボックス化とか発生してパフォーマンス的に若干不利でしたっけ?覚えていません。

時間、日付

JavaDateが、クソ過ぎて…Calendarと組み合わせないといけないとか面倒です。

なお、一通り終わって気付きましたが、Java 8 からLocalDateTimeという型が増えていたそうですね。知りませんでした。*4
だったら、Dateは非推奨にしろよ!と正直思いました。

Stream API

C#、というか.NETでは、Linqを拡張メソッド等を用いて、だれでも簡潔に利用できるよう追加しました。
Javaでは、いったんstreamに変換してから、拡張メソッドっぽい*5ものを呼び出して、Linqっぽい処理を行います。

…使いやすいですか?

この辺りはC#が神な部分だなぁ、と思いました。

話ずれますけど、C#Linqは、Pythonに相当影響を受けたように感じました。
Pythonのリスト周りは、標準機能だけで十分に充実してますし。

検査例外

正直、鬱陶しいと感じました。
いつ、検査例外を使うべきか、明確な指針がない*6のは、仕様として導入しておいてどうなんだ?とは思います。

Javaの良かったと思う点

DB周り

開発では、Ebean使って、コードファーストでDBを使っていました。いわゆるentity、で良いのでしょうか?

かなり簡素な仕組みであり、個人的にはなかなか使いやすかったです。*7

でも、entityを直接参照するのは、絶対に止めるべきだとも思いました。別のクラスで隠蔽すべきですね。リポジトリ等を作るべきです。
staticのfindフィールドを用意するとか、あれは危険すぎます。

列挙型

良かった点として挙げていますが、C#に慣れた身としては、正直違和感がありました。

言語 扱い 特徴
C# 値型 Flagsサポート。拡張メソッドで値を紐づけられる
Java 参照型 シングルトン。メソッド等で値を紐づけられる

Javaの列挙型は参照型ですが、シングルトンだから==での比較が可能です。
演算子オーバーロード、付ければよくないですかね…?

でも、メソッド等を内部に宣言できるのは、使い方次第で有用だと思います。
味をしめて、やりすぎなければ、の話ですが…

幅広く扱える

Play Frameworkもそうですし、Spring Framework などもあるので、そう思うのですが、コミュニティが活発で、新しい仕組み等を入れて、便利にしよう!という柔軟さを強く感じました。

その点、C#は鈍重な部分があると思います。

Entity Framework、便利だけど裏で何やってるか分からんよ…

Prism 難しいよ…

Web開発

気づいたらJavaばかり書いていたので、Webについても。

Play Frameworkを使っていたので、ルーティングについてはファイルに定義し、定義されたメソッドが呼ばれる、という形式です。
なので、Javaの処理を作成したら、実際にリクエスト投げる、という感じで開発していました。

Java開発は、上のような疑問はあったものの、さほど苦労はしませんでした。

始めたばかりの頃

最初に質問したのは、

これ、どうやってリクエスト投げるんですか?

でした。すると、ブラウザにURL打ち込むんです!という、とっても親切な回答が返ってきました。

なお、やってらんないと思うまでに時間はかかりませんでした。

Accept: application-jsonの場合どうするんですか?には、テストページ(更新する気なし)を渡されました…

やってられないので

PowerShellでリクエストもレスポンスも確認できるの、作りました。

リクエストは、JSONで送られてきたり、フォームから来たり、URLのパラメーターで来たり、様々でした。 全部PowerShellで実現できるのですが。

とはいえ、いくつかひな型を用意して、ちょっと書き換えたらだれでも使えるようにしただけです。

まさかね、過去に自分が書いた記事が、役に立つとは…

複数ユーザーの自動登録等が必要な場合も、実際のWeb APIを通してPowerShellから呼べるようにしていました。
DBを操作すれば不要なのですが、やはり実際の流れを通したほうが、安心感は得られます。*8

これ、効率的にやれるツールとかあるんですか?あったら教えてほしいです。

PowerShell内容

流れだけですが、こんな感じでした。

  1. サーバーに入るための資格情報を生成(全てのリクエストに付与する)
  2. ログインAPIを呼び、セッションを保持する(ログアウトまで使いまわす)
  3. テストしたいAPIを呼び、結果を受け取って表示する
  4. ログアウトAPIを呼ぶ
  5. セッション、資格情報を破棄する

実際にブラウザを使うと、毎回ログインが必要で、非常に面倒でしたが、PowerShellだと実行するだけで良いので、楽です。
もちろんVSCodeを使いました!

リクエストごとにPowerShellスクリプトを作成していたので、呼び出しの付け替えも柔軟でしたし、とても便利でした。

…便利だって教えたのに、先任者は使ってくれませんでした。
そのせいか、途中から自分の生産性は非常に良かったです。

Webページ作成

簡単なものですが、ページの修正も行いました。

静的と動的を使い分ける感じ、なかなか勉強になりました。

とても基礎的なことがわかりました。

  • Form要素の各要素は、nameで見分ける
  • class要素は半角スペース区切りで複数指定できる
  • submitするだけでも、JavaScriptが必要なときはある
  • イベントもいろいろある

イベント多用すると、カオスになるというのはよく分かりました。

おわりに

なんか、半分ぐらい文句ですが(笑)
個人的には、Javaだけでなく、思ったより幅広い経験になりました。

なお、単体テストの状況も非常に悪かったので、必要な範囲で作っていました。
いいですね、単体テスト。便利。

JUnitで、サーバーの起動を前提にするとか、DB接続を前提にするとか、正気とは思えません。
どこでも、前提なしに実行できることが重要だと思っています。

でも、Play Framework のFakeApplicationという機能を使っていないので、使ってみたらよいかも、とは思ったりしました。

おわり


*1:これは未だに覚えられていない

*2:Javaでは、参照型の==は、参照の同一性を確認する。C#では==自体をオーバーライドできるため、文字列は内容比較を行うよう実装されている

*3:Playでは、publicのフィールドはプロパティとして扱われるため、実は不要だったりするが

*4:先任者も使えとは言わなかった

*5:Javaだと単なるメソッド?

*6:意見等はある。公式的に、いつ使うべきか、というものがなかなか見当たらない印象

*7:C#のEntity Frameworkで、コードファースト使ったことがないので、そちらを経験したら心変わりするかも

*8:バグが見つかったこともある