目的次第でコーディングは千差万別なんだなあと実感した話
はじめに
この記事は Colorful Palette アドベントカレンダー 12/3の記事です。
株式会社Colorful Paletteでサーバサイドエンジニアをしております、ちくわです。
Colorful Paletteでは、「プロジェクトセカイ カラフルステージ! feat. 初音ミク(以下、プロセカ)」の開発・運用を担当しております。
本稿は、ひよっ子エンジニアの私が今まで携わってきたプロジェクトを紹介し、開発の目的によって重視すべき点が変わることを実感しよう、という趣旨の記事です。
かっこいい技術とかすごいノウハウの記事ではございませんので、エンジニアの方もそうでない方も、気軽にご覧いただけたら幸いです。
「開発の目的によって重視すべき点が変わる」とは
私はエンジニアとして従事する中で、「良いものを作ること」を目標の一つに掲げております。
Colorful Paletteにおいても最高のものづくりを目指して、日々の業務に励んでおります。
しかし「良いものを作る」と一口に言っても、その観点はいろいろあります。
動作が速い
動作が安定している
保守性が高い
開発・運用コストが低い
例)インフラ費用、開発期間など
etc…
これらの観点を高水準で満たすのを目標に、業務に取り組んでいます。
しかし、私が今まで所属してきたプロジェクトでは、上記の観点に各々の優先順位があるように感じました。
開発するシステムがどこで、誰に、どのように使用されるのかといった目的次第で、どの観点を特に大事にするかが変わります。
それが本稿のお題である「開発の目的によって重視すべき点が変わる」ということです。
紹介するプロジェクト
本稿では、私が今まで経験してきたプロジェクトのうち以下の2つを取り上げます。
プロセカの開発
私は主に以下の業務に携わっております。
主な使用言語はJava(spring boot)、Angularです。
各バージョンにおけるサーバーサイドの開発
管理ツールの開発
各バージョンのリリース作業
保険系Webアプリ開発
保険を扱う企業の社員および顧客向けのWebアプリケーションで、主に以下の機能を持つシステムの開発を目的としたプロジェクトです。
主な使用言語はJava(struts)・JSPです。
各商品の申し込み、解約
契約内容の照会
金額計算
書類発行
上記の両プロジェクト共にJavaを利用しておりますが、実態はとことん目指すものの異なるプロジェクトでした。
コーディング例についても、Javaで記述して紹介できればと思います。
(単純な例ですので、軽い気持ちでご覧ください)
コーディング例
前提
一つのフィールド・コンストラクタ、ゲッターで構成された簡単なクラスを,
2つ定義しておきます。
class Hoge {
private final int hogeInt;
public Hoge(int hogeInt) {
this.hogeInt = hogeInt;
}
public int getHogeInt() {
return hogeInt;
}
}
class Fuga {
private final int fugaInt;
public Fuga(int fugaInt) {
this.fugaInt = fugaInt;
}
public int getFugaInt() {
return fugaInt;
}
}
上記のクラスを元に、「Hogeクラスのオブジェクトを複数格納したリストから、Fugaクラスのオブジェクトを複数格納したリストを作る(ただし、fugaIntが2のオブジェクトはリストに格納しない)」というような処理を、それぞれのプロジェクトの思想に基づいて記述してみます。
プロセカの開発におけるコーディング例
現在携わっているプロセカの開発では、概ね以下のように記述することが多いです。
// Hogeクラスのオブジェクトを複数格納したリストを用意
List<Hoge> hogeList = List.of(
new Hoge(1),
new Hoge(2),
new Hoge(3)
);
// Fugaクラスのオブジェクトを複数格納したリストを作成
List<Fuga> fugaList = hogeList.stream()
.map(hoge -> new Fuga(hoge.getHogeInt()))
.filter(fuga -> fuga.getFugaInt() != 2)
.collect(Collectors.toList());
場合によってはFugaクラスにgenerateメソッドを用意したり、filter処理が挟まったりすることもありますが、リストや繰り返し処理は主にstreamAPIを利用するのが主流です。
(どうしても複雑になりすぎる、処理の重複が許容できない等の理由がある場合、forやwhileを利用した他の書き方をすることもあります)
先述したクラスについても、実際には@Getterや@RequiredArgsConstructor等のアノテーションを利用して定義しています。
保険系Webアプリ開発におけるコーディング例
一方で、以前携わっていた保険系Webアプリ開発では、以下のように記述していました。
// Hogeクラスのオブジェクトを複数格納したリストを用意
ArrayList<Hoge> hogeArray = new ArrayList<>();
hogeArray.add(new Hoge(1));
hogeArray.add(new Hoge(2));
hogeArray.add(new Hoge(3));
// Fugaクラスのオブジェクトを複数格納したリストを作成
ArrayList<Fuga> fugaArray = new ArrayList<>();
for (int i = 0; i < hogeArray.size(); i++) {
int hogeInt = hogeArray.get(i).getHogeInt();
if (hogeInt != 2) {
fugaArray.add(new Fuga(hogeInt));
}
}
ラムダ式やstreamAPIを利用せずに、for文やif文などの単純な処理を組み合わせて、実現したい処理を記述しています。
それぞれの特徴
それぞれのプロジェクトのコーディングを経験した中で、私は以下の特徴があるように思いました。
プロセカの開発におけるコーディング
ワンラインでスッキリ処理が収まるので見やすい
ArrayIndexOutOfBoundsException等の想定外が起きにくい
学習コストがもう一方より少し高い
保険系Webアプリ開発におけるコーディング
プログラミングやJava初学者でもジョインしやすい
行数やネストが嵩み、Typoや想定外の挙動を誘発しやすい
どんな目的に向けて開発しているか
私がジョインした経験をもとに、それぞれのプロジェクトがどのような観点を重視して開発しているかを考察します。
プロセカの開発
ユーザーにより良い体験を提供したい
→ 改善を念頭に置いて開発する
→ より良い記述の方法があれば、既存のコードにも取り入れる
→ 機能を継続して開発し続ける
→ 記述しやすくレビューしやすい、見通しの良いコーディングをする
保険系Webアプリ開発
顧客の金銭や人生に関する情報を多く扱うため、安定して稼働するシステムを開発・運用したい
→ 開発時には影響範囲を小さくし、既存で安定して稼働している実績のあるコードは必要最小限の修正に留める
以上、作るものや使う人が異なれば重視する観点も異なる、という一例でした。
「私が体験したことのあるプロジェクトではこうだった」という内容のため、何を重視するのかはプロジェクトの数だけ存在するのだと思います。
まとめ
ここまで、私が今まで体験してきたプロジェクトの紹介とともに、目的次第で重視する観点が変わる話を展開しました。
プロセカの開発をするのも、保険系Webアプリの開発をするのも、あるいは他のシステム開発に従事するのも、広く言えば同じエンジニアとしての業務です。
新米エンジニアだった(今もですが)当時の私は、元いた業界から一念発起してアプリゲーム業界に飛び込んだ際、考え方の違いにとても驚きました。
所属するのがどのようなプロジェクトであれ、「何を目的として開発をするのか」を都度意識しながら業務に従事する適応力は、エンジニアにとって必要な能力の一つだなと感じます。
最終的に何を成したいのかというゴールを設けて、そこから逆算して何をするべきか考え、効率的に仕事をすることを習慣づけたいものです。
おわりに
この記事を少しでも共感しながらご覧いただけたなら、筆者冥利に尽きます。
ここまでご覧いただきまして、ありがとうございました。
次回の記事も乞うご期待くださいませ。