2025年6月17日

若手モバイルエンジニアが設計をする際によく考えてることを書いてみた!


Content
こんにちは、はるです!

本記事は、オブジェクト指向などを考慮したクラス設計などのコードレベルの設計に焦点を当てた内容になっています。 もちろん、ここでの考えはモバイルアプリ開発やその他開発でも汎用的に使うことができる考え方です。

執筆をしようと考えた背景

まず、現時点でも設計で迷ったり間違えたりする時は数多くあります。
ただ、自身がエンジニアとして就職した当時を振り返ると”設計”に関してはそもそも概念を掴めなかったり、参考書やサイトを見ても理解が進みませんでした。
他の若手エンジニアの方も同様に苦しんでいる人がいるのでは?と思い、役立てればと思い執筆にいたりました。
今回は、普段私がたくさん意識していることのうち2つを紹介していきます。

これから執筆する内容はあくまで個人の意見であり、決して正解を意味したり、またそれを押し付けるようなことが目的ではありません。

1. 抽象的思考と具体的思考の操作

これが最も要求される思考であり、最も難しい思考であると考えてます。
あらゆる事象が、因果関係(原因と結果)から成り立つように”物”も全て具体と抽象で考えることが出来ます。
また、抽象化というものは縦方向と横方向に分けることが出来ます。

横方向

例えば、”りんご”・”ぶどう”・”れもん”を例として考えてみましょう。
これら3つは下記のように抽象化出来ると思いませんか?

  • 食べられるもの
  • 皮を剥けるもの
  • 色味をもつもの

このように各物が持つ特性を並べたものは横方向の抽象化になりやすいです。
Appleが提唱している”プロトコル指向プログラミング”が近いでしょう。

縦方向

また、物は縦方向に具体化及び抽象化することが可能です。
「スマートフォン」を例にして考えてみましょう。
上から下に進むに伴い、抽象的になっていきます。

スマートフォン

携帯電子機器

電子機器

機器

物(オブジェクト)

これらはエンジニアがよく使う設計思想である”オブジェクト指向プログラミング”にて使う考えです。

抽象化及び具体化は難しい

このように抽象化と具体化の操作は相当なバリエーションがあります。
クラス設計などを考える上では、この様々なバリエーションの中からどのように抽象化すればいいか?を見抜くことが一番大切なスキルです。
これを見誤ると悲惨なことになりやすいです。

  • 過度に抽象的→抽象化の利点が無い
  • 過度に具体的→抽象化クラスの使い回しが出来ない

そして、恐ろしいことに設計の正解/不正解は時と場合で無慈悲に変わります。
今まではこの抽象化で良かったのに新たな仕様だけ微妙に異なり、抽象化が適用できない。
既存の仕様に対して大規模な変更が要求されたり…。
そのため、自身が作っているプロダクトの展開予測(ビジネス的視点)やSIerであれば顧客の特性(仕様変更依頼を頻繁に出すなど)の判断が必須になっているのです。
そして、それを知るためにはプロダクトを知り、顧客を知ることが非常に重要なのです。
この領域は、AIもまだ出来ておらず人間ならではのいわゆる”ソフトスキル”が要求される場面ではないでしょうか。

話を戻し、次の章ではどのようにして抽象化する方向を決めるべきなのか?をお話ししていきます。

目的と手段の分離

社会人になると度々指摘される内容です。
これが前項目の考え方を支える補助役としての思考の種類です。
そもそも、わざわざ設計において抽象化クラスを使い、抽象化及び具体化を行う目的はなんでしょう。
本質は3つあると考えてます。

  1. コードの共通化ができる

    • 同じ振る舞いを抽象化クラスに閉じ込めることができる
    • 例えば、for文で同じ抽象化クラスを持つ各インスタンスに同じ処理を適用できる
    • これにより、コードの重複を減らし、保守性を高めることができる
  2. ドメイン知識(業務知識のこと)が浅くても実装ミスを防ぐことができる

    • 新しい機能を追加する際に、抽象化クラスが「ここに実装が必要」と教えてくれる
    • これにより、実装時に必要な要素が明確になり、ミスを防ぐことができる
    • 例えば、新しい種類の果物を追加する際に、「色」や「皮を剥く方法」などの必要な情報の実装が強制される
  3. テストのしやすさ(テスタビリティの向上)
    ⚠️テストの話を持ち込むと長引いたり難しくなるので今回は簡単に紹介

    • 抽象化クラスを作っておくことでモックの挿入が行いやすい
    • DI(依存性注入)の導入に役立つ

抽象化を考えるときはこれらの目的を達成できるかどうかで考えます。

具体例

例えば、あなたがSNSアプリを開発しているとします。
当該アプリの開発初期段階では「一般ユーザー」のみサポート予定ですが、将来的に「公式ユーザー」を追加する予定があります。
このような状況で、よくある失敗パターンは「今は一般ユーザーしかないから」という理由で、ユーザー関連の機能をすべて直接「NormalUser」(一般ユーザークラス)に実装してしまうことです。
この設計では、将来「公式ユーザー」を追加する際に大規模な実装が必要になります。
どちらもユーザー名やユーザーIDという特性を持つし、プロフィールを変更するという振る舞いだって持ちます。
一般か公式かという細かい違いにも関わらず、公式ユーザー追加の際に初めから実装する必要があるのです。
これでは開発コストは単純に2倍になりますね。

より賢明なアプローチは、開発初期から「将来的な拡張」を見据えて抽象化しておくことです。
具体的には、「User」という抽象クラスを作成し、一般ユーザーの実装は「NormalUser」という具体クラスで行います。
そして、公式ユーザーの追加の際に、Userクラスを継承した「OfficialUser」という具体クラスを追加します。
こうすれば、一般ユーザーと公式ユーザーどちらにも共通している処理や特性は使いまわすことができます。
また、仮にOfficialUserクラスの実装を新人が行う場合もUserクラスを継承さえしていれば実装が不足していた場合ビルドエラーが教えてくれるので上司側の指導の手間も省けます。
テストに関してもNormalUserやOfficialUserといった各具体クラスの中身をモックに差し替えればいいだけなので容易いです。

これで、先ほど掲げた1-3の目的が抽象化をすることで達成できたわけです。

まとめ

設計において抽象化と具体化を考える際は、以下の点を意識することが重要です:

  1. 抽象的思考と具体的思考の操作

    • 横方向と縦方向の抽象化を理解する
    • 適切な抽象化の度合いを見極める
    • ビジネス的な視点を考慮する
  2. 目的と手段の分離

    • コードの共通化による保守性の向上
    • 実装ミスの防止
    • テストのしやすさの確保

設計は難しいですが、これらの基本的な考え方を理解しておくことで、より良い設計ができるようになると思います。

しかし、設計というのは一朝一夕では身につかないと考えています。
重要なのは、自分なりに”設計”というものを意識してひたすらコードを書いて失敗したり、上司の方々に指摘してもらうことだと思っています。
実装力は業務を何気なく行っても向上しますが設計力は違います。意識した人とそうでない人では明確な差が現れる領域であり、先ほども記載したようにビジネス的視点が絡むためAIが完全に乗っ取ることは非常に難しい領域です。
ですから、たくさん設計を考えて実装をして失敗を繰り返しましょう!!!

2025年6月17日 若手モバイルエンジニアが設計をする際によく考えてることを書いてみた!

Category モバイル

ご意見・ご相談・料金のお見積もりなど、
お気軽にお問い合わせください。

お問い合わせはこちら