アーキテクチャを説明するために

2020/11/08に公開

アーキテクチャを説明するために

まず最初に聞きたいことは以下のようなプログラムを見たとき
気持ち悪いか別に何も感じないかを考えてほしい

const Test = () => {

    // データを表示させる為の変数群

    // 別のAPIからJSONデータを取得

    // 別のAPIからJSONデータを変換

    const handleSubmit = (e) => {
      // ボタン押した時の処理
      // 画面を表示させる為に変数群にアクセス
    };

    return (
        <>
          // 画面を表示させる HTML
        </>
    );
};

export default Test

そもそもアーキテクチャって?

基本設計や設計思想という物だ。

まずアーキテクチャにも色々種類がある。
IT業界における「アーキテクチャ」の種類だと大体以下に大別できる

  • ソフトウェアアーキテクチャ
    • ソフトウェアにおける構築スタイル、または構築方式のこと
  • システムアーキテクチャ
    • セキュリティ設定だったり、そもそものOSだったり、開発の下地になるもの
  • エンタープライズアーキテクチャ
    • 巨大な組織の資源配置や業務手順、情報システムなどの標準化、全体最適化を進め、効率よい組織を生み出すための設計手法。

ソフトウェアエンジニアが気にする所は当然ソフトウェアアーキテクチャということになる。
ソフトウェアアーキテクチャでも大別すると以下になるのではないですかね。

  • フロントエンドのアーキテクチャ
  • サーバーエンドのアーキテクチャ

じゃあ今回必要になるアーキテクチャとは

そもそも作るものによって最適なアーキテクチャは変わる。
これだけ覚えていれば大丈夫などという物はITに存在しない。
※食べてはいける。(今だCOBOLの仕事は絶えない。)

ただ、個人的な話をすればやはりその時代その時代で最適な物は変わるし
作るシステムによっても変わる。なにも最新なものが全て良い訳ではないのだ。
※世の中にはWindows2000で動くシステムが超大企業にも存在する。

ただ、最新を追いかけないのはエンジニアではない。
一重に新しい物は楽になる。
新しい技術でアイディアを早く実現できるのであれば
それを選定すべきだし、知識がないとその選択肢がなくなる。

javascriptは今現在まだまだフロントエンドで使われる事が多いので
フロントエンドのアーキテクチャを採用している企業が多いということになる。

なので選定するのはフロントエンドのアーキテクチャである。

なぜアーキテクチャのような考え方必要か

チームで開発するから。

この一言しか存在しない。
一人で作りつづけるのなら誰も文句は言わないし、大規模な変更に関しても
ある程度は対応可能だ

ただ、人が手を加えるなら話は別だ。
別の思想で作られたプログラムに対して別の思想で手を加えたなら

あっというまにスパゲッティコードが作成され
変更しようという時には誰も手が付けられない代物となるだろう。

1から一緒に作り始めるなら何らかの設計の方針が必要だ。
議論するにも何かが必要なのだ。

そのために考え方の一方通行化、思考の統一という意味でも
名前が付けられた概念が必要になる。

なぜソフトウェアアーキテクトが必要なのか

以下に示すのはFacebookが提唱しているFlux

図

View –> Action –> Dispatcher –> Store –> View …
Fluxの特徴は情報の伝播を1方向に制限している

オブジェクト間の情報の流れが1方向になってるように見える。

  • View
    • Reactがになう部分
  • Action
    • Actionは『何を、どうした』という情報を表現するオブジェクト。
      例えば、TODOアイテム(idはXXXで、textは◯◯)を新しく1件追加した、といったアクションを表現してる。
  • Dispatcher
    • PubSubを担うオブジェクト。pub/subとは
      ActionCreatorからDispatcherに対してActionオブジェクトをdispatch(速達)されると、
      Dispatcherはcallbackを実行する。これがStoreへの通知を実現してる。

      ざっくりいうと、ActionCreatorからの通知を貯めて順次実行するための機能としてとらえると分かりやすいかもしれない。
      タスクを貯めていて、順次それに対応した行動をするような。

  • Store
    • 状態を管理するオブジェクト。
      例えば TODOのリストであったり、個々のTODOの具体的な内容、達成状況や期限といった情報などを一括で保存。

引用URL

ものすごい余談な例え

例をあげるなら、料理で例えてみよう。
とある人が独自の料理を作り上げた。
その料理は以下の材料が入っている

  • ジャガイモ
  • 人参
  • タマネギ
  • 豚肉

そうして出来た物があるとする。

ある人間が手を加え、カレーだと思ったため
以下を加える

  • リンゴ

だが本当は肉じゃがを作っていたために
ほんのりりんご味のする肉じゃがが出来てしまった。

だが、食べれるものという必要最低限の仕様は満たしている。

そのあとレシピを作った人間は誰もいなくなり。
以下の材料だけが残された

  • ジャガイモ
  • 人参
  • タマネギ
  • 豚肉
  • リンゴ

これだけではほとんどの人間はカレーだと勘違いし
出汁も、砂糖の存在も忘れ、スパイスをぶち込むだろう。

そしてお店の経営者は肉じゃが専門店だと思って内装を進めていたのに
和の雰囲気でカレーを食すことになってしまった。

とまぁ。違う気がしないでも無いが何かしらの意思統一を測らないと
まずいことになりそうだ。
というのは直観的に理解できると思う。 苦情は受け付けない。

ではフロントエンドのアーキテクチャについて

フロントエンドにおけるアーキテクチャとの向き合い方

フロントエンドの開発では、ReactやVueといったフレームワークを活用した開発が一般的だ。
しかし、これらのフレームワークはビュー部分しかカバーしていない。
※ 大体公式が ユーザインターフェース構築のための JavaScript ライブラリと言っている。
フレームワークか、ライブラリかという話が良く出るがあまり気にしないで進める。

以下に示すように、そういったフレームワークがカバーしていない箇所はおおむね以下のような感じだ。

  • リッチなUIを実現するためのUIコンポーネントの活用
    • マテリアルUIとか。
  • ルーティングの実現方法
    • クライアントサイドでURLに応じた画面切り替えを行う仕組みが必要になる。
      この仕組みをルーティングと呼ぶ
  • ビューで扱うモデルやビジネスロジックを実装するクラスなどの責務配置
    • ここがまさにアーキテクチャが担う箇所。

Fluxの派生のRedux

まぁFluxはざっくり分かったけど最初からその仕組み作るの?
という疑問が生まれるかもしれない。

恐らくこれから仕事をしていくうえで作る事になるかもしれない。
だが、誰かが用意してくれた物を使う方がよほど楽だし、情報を得やすい。
そこでReduxという状態管理ライブラリを導入してみよう。

参考図
参考URL

Fluexとはだいぶ違うように見えるが、言ってしまえば

アクションを受け取った後、それに対応した物を順次実行し状態を保存して置くもの

ととらえるとなんとなく分かるかもしれない。

Fluexで言えばAction Dispatcher Storeを担う箇所と捉えられる。

とりあえずの実践編

では以下に示すような図(参考URL)を発見したので見てみよう。

Reduxの標準的な構成(action、reducerなど)に以下が追加されている構成だ。

  • view-model
    • ビューに必要な情報を保持する
      ※Reduxはビューの状態は管理するが、外部APIを仕様した時の状態などは保持しない。無理やり入れるとviewの状態とは別の状態が入ってしまうので設計的によろしくない。
      設計の大原則は依存性は少なく だ。
  • service
    • apiを使用してバックエンドが提供するビジネスロジックを呼び出す
    • ビューモデルとリクエスト/レスポンスの変換を行う
  • api
    • バックエンドのAPIを呼び出す

common
共通ライブラリ(ID生成や暗号化処理など)

stereotype

だが、バックエンドと通信しません!
ただ画面見せるだけのサービスですわ!
などなら外部APIなんか呼び出さないのでReduxだけで不自由なく設計できるし、強固だ。
※もし君がリッチなWebページを作りたいだけならWebGLや、アニメーションなどのプログラミングを学んだ方が良い。

以上がなんとなくなアーキテクチャと設計の話だが、
プログラムを作る前に色々考える事が多いのが設計の世界だ

ただ設計が良ければチームでのプログラミングがより円滑になる
プログラミングを実際にする時も設計が頭に入っていれば
自分がなんの責務を担う箇所を作成しているのかが分かる

そうすれば強固なプログラミングを作る事が出来るはずだ。

今までの説明を聞いた後、冒頭の質問をしよう。

このプログラムは気持ち悪いだろうか、良いだろうか。

const Test = () => {

    // データを表示させる為の変数群

    // 別のAPIからJSONデータを取得

    // 別のAPIからJSONデータを変換

    const handleSubmit = (e) => {
      // ボタン押した時の処理
      // 画面を表示させる為に変数群にアクセス
    };

    return (
        <>
          // 画面を表示させる HTML
        </>
    );
};

export default Test

このプログラムを実際に書いた場合、百行クラスのプログラムになる事は想像に難くない。

このプログラムは責務が多すぎるのだ。

Discussion