本書は@pospomeがサーバサイドアプリケーションのあれこれに関してまとめたものです。
pospome。サーバサイドエンジニア。DDD、実装パターンのようなアプリケーションアーキテクチャが専門。Twitterは@pospome。ブログは「pospomeのプログラミング日記」。共にアプリケーションアーキテクチャ、システムアーキテクチャ、Go言語、GCPを中心にアウトプットしている。キャラクターは羊ではなくポメラニアン。
筆者が"Easy","Simple"という概念を初めて知ったのはRails Conf 2012 Keynoteの発表がきっかけでした。Easy,Simpleという概念はプログラミングにおいて重要な概念です。本章では実装におけるEasyとSimpleについて筆者の考えを述べます。
プログラミングにおけるSimpleは"単純"という意味です。単純な実装はSimpleな実装と言えるでしょう。Simpleな実装の具体例はGo言語のdatabase/sqlパッケージです。database/sqlパッケージにはDBを操作するために必要な機能が実装されており、DBを操作するためにはリスト1.1のようにSQLを直接指定する必要があります。
DBのレコードを取得するコードはリスト1.2です。レコードを取得する際はdatabase/sqlパッケージのRows.Scan()を利用します。取得対象の列は1つ1つ引数に指定する必要があります。
database/sqlパッケージはDBを操作するパッケージなので、SQLを直接指定したり、取得対象のテーブル列を指定するのは自然なインターフェースでしょう。"DBを操作すること"に対してシンプルなインターフェースが提供されています。シンプルであるがゆえに、DBを知っているエンジニアであれば、このパッケージの使い方に違和感を覚えることはないでしょう。
一方、プログラミングにおけるEasyとは"簡単"という意味です。"Simple = 単純"と似ているように思えますが、単純と簡単は異なる性質を持ちます。先程database/sqlパッケージを例にSimpleな実装を説明しましたが、実際にdatabase/sqlパッケージをそのまま利用して開発するかというと、そうとは限りません。おそらくORMを利用することが多いでしょう。では、なぜ実際の開発でORMを利用するのでしょうか?それはおそらくORMがdatabase/sqlパッケージよりも便利だからです。筆者は過去にGo言語のORMを調べたことがありますが、どのORMも以下の2つの機能を備えていました。
例えばGo言語のORMである"GORM"はリスト1.3のようにデータを取得し、userという構造体に取得した値をマッピングすることができます。
これらの機能はGo言語に限らず他の言語のORMも備えているものでしょう。わざわざSQLを書く必要がなく、取得した値を構造体にマッピングする必要もありません。簡単なSQLだけで完結するアプリケーションであれば、SQLを知らなくても実装できてしまいます。とても便利な機能です。database/sqlよりも簡単にDB操作が行えるGORMはdatabase/sqlに対して相対的にEasyな実装であるといえるでしょう。
このような説明だけだとSimpleな実装よりもEasyな実装の方が優れているように感じるかもしれませんが、そうとは限りません。Easyな実装はSimpleな実装にはない複雑性を抱えてしまう傾向にあります。例えばモデルに対するタグの指定であったり、Associationsの種類である"Beloings To","Has One"の理解であったり、GORMが提供するEasyな実装を利用するためには、こういった概念を理解する必要があります。もし、これらが期待した通り動作しない場合、"なぜ動作しないのか?"を調査するにはさらに多くの時間をかけることになるでしょう。この他にも"実際に発行されるSQL文を考慮して利用しなければいけない"、"複雑なマッピングパータンはサポートされていない"など、Simpleな実装にはなかった複雑さを抱えることになります。
Simpleな実装とEasyな実装はどちらが優れているのでしょうか。結論から言うと、ケースバイケースです。しかし、Simpleな実装とEasyな実装の性質を具体的に考えると、どちらが適しているのかが見えてきます。例えばリスト1.4はSimpleなメール送信の実装です。Simpleな部品を組み合わせてメール送信という目的を達成するイメージです。
Simpleな実装はSimpleがゆえに目的を果たすまでのステップが多くなる傾向にありますが、Simpleな部品を組み合わせるという性質上、利用者のニーズに幅広く対応することができる実装になります。
一方、実際のユースケースとしてメールのタイトルと本文が固定であったり、添付ファイルが不要である場合は、より目的に特化した使いやすいEasyな実装としてリスト1.5のような関数を提供するだけで十分でしょう。
Easyな実装はEasyがゆえに目的を最短で達成できる実装を提供しますが、ある程度ユースケースが限定される傾向にあります。Simpleな実装ほど幅広いニーズに対応できるとは限りません。
筆者はSimpleな実装は不特定多数の利用者が想定されるライブラリに向いた実装であり、Easyな実装はWebサービスなどの特定のユースケースに特化することが想定できる場合に向いた実装であると考えています。筆者はWebサービスのサーバサイドアプリケーションエンジニアとして働いていますが、Webサービスの開発では特定のユースケースに特化した実装を提供すれば十分なケースが多いので、比較的Easyな実装を提供することが多いです。別の観点だと、アプリケーションコードの場合はその都度実装に求められるニーズが変わるので、実装時に最適な実装方法を選択することが多いです。その結果、Easyな実装を選択することが多くなります。一方で、筆者は社内で共通利用するライブラリの開発をすることもあります。その際は不特定多数のユーザーに向けてSimpleな実装を提供することを心がけています。Simpleな実装が適しているのか、Easyな実装が適しているのか、というのはケースバイケースですが、このような性質の違いが適切な実装を導くヒントになるでしょう。