タオバオの航空券注文業務と複雑なフォームアプリケーションの分離

タオバオの航空券注文業務と複雑なフォームアプリケーションの分離

背景

Web アプリケーションでは、複雑なフォームにはインタラクティブな要素が豊富に含まれており、複雑なビジネス ロジック、絡み合った要件、頻繁に変化する要件があります。簡単に不明瞭で暗いものになり、さまざまなコード臭の原因となることがよくあります。この典型的な複雑なアプリケーションを対象に、この記事では、Taobao 航空券注文を例に挙げて、フォームによってもたらされる複雑さを整理して理解するためのアーキテクチャ モデルを提案します。

モジュールとコンポーネントの分割

複雑なフォームを解決するための最初のステップは、それをモジュールに分割することです。

概念的には、再利用と分離の便宜上、モジュールは機能の結合度に応じて分割する必要があります。密接に関連し、頻繁に通信および相互作用する機能は、1 つのモジュールにグループ化する必要があります。モジュール間に依存関係があってはなりません。これはしばしば「高凝集性と低結合性」と呼ばれます。

下の図に示すように、Taobao 航空券注文ページは 7 つのメインモジュールに分かれています。

モジュール分割が完了したら、次はモジュールを構成するコンポーネントを確認します。

モジュールとコンポーネントの違いについて。一般的には、以下の3つの側面から考えます。

ビジネスロジックは関係していますか?

HTML を含めるかどうか。

ある程度の独立性があるかどうか。

「モジュール」は、「html」、「css(画像は css の一部とみなされます)」、および「javascript」を含むコードのセットとして定義されます。モジュールは主に Web テンプレート テクノロジ (velocity、freemarker、php など) を通じて適用されます。 HTML が含まれているため、モジュールはサーバーによってマージおよびロードされ、最終的にユーザーのブラウザにプッシュされる必要があります。また、「モジュール」とは、ある一定の独立した業務ややり取りをまとめたものであり、他のページから参照できるものがベストです。独立性が高ければ、共同開発にも役立ちます。実際の開発では、複数の人が複数の独立したモジュールを並行して開発することで、効率を向上させることができます。

「コンポーネント」は、「css」と「javascript」のみを含むコードのセットとして定義されます。 HTML が含まれていないため、コンポーネントは JavaScript 経由で非同期的に読み込むことができます。この非同期読み込み機能により、コンポーネントはモジュールよりも再利用がはるかに簡単になります。コンポーネントにはビジネス ロジックがないか、共通のビジネス ロジックが少量しかありません。ビジネス ロジックが増えるほど、コンポーネントの再利用性は低下します。

モジュールとコンポーネント間の通信

コンポーネント/モジュール分割の目的は、比較的独立した機能を互いに分離することです。分離の問題は、モジュールとコンポーネントを分割することで解決されました。実際には、モジュール間には協力関係が存在します。モジュールは軽量な方法で連携する必要があります。一般的に、分離とデカップリングを改善するには、モジュール間の通信にブロードキャストを使用し、コンポーネント間の通信にイベントを使用することを検討できます。

下図は、Taobao航空券注文ページのデータフローです。

後の段階では、さまざまなモジュールが小さな機能で拡張される可能性があります。たとえば、不定期のプロモーションなど。イベントブロードキャストを使用すると、異なるモジュール/コンポーネント間で新しい機能を追加することによる影響を軽減できます。タオバオ航空券注文アプリケーションでは、ブロードキャストコンポーネント通信は主に以下の目的を達成するために使用されます。

1. 情報を得る。

通知の特徴は非同期通信です。ブロードキャスト イニシエーターは、他のフォロワーが処理を完了するのを待たずにイベントをリリースするだけで済みます。これを非同期ブロードキャストと呼びます。たとえば、フォーム モジュールの内容の変更は、注文金額を表示するモジュールに通知する必要があり、注文金額を表示するモジュールはイベントを受け取った後に金額を変更する必要があります。

このタイプの通信に基づいて、各モジュールは独自の処理を実行し、外部の注意の時間をブロードキャストするだけで済みます。非同期ブロードキャストのもう 1 つの利点は、システムがより堅牢になり、イベント リスナーの不適切な使用によってブロードキャスト送信者が誤動作することがなくなることです。

2. データのリクエスト

たとえば、モジュール 2 (乗客フォーム)、モジュール 4 (連絡先住所)、モジュール 7 (金額計算) からモジュール 6 (提出責任者) をクリックする必要があります。特定のデータの送信を取得します。データを要求するシナリオの特徴は、ブロードキャスト イニシエーターが次のステップに進む前に、タイム プロセッサが処理を完了するまで待機する必要があることです。これを同時放送といいます。同時放送の適用はやや混乱を招きます。このコードでは、原理と応用について説明します。

このメカニズムに基づいています。送信モジュールは、包括的な検証、フローティング レイヤー、ネットワーク要求、および例外処理のみを担当します。リクエストの具体的な内容は他のモジュールによって決定されます。後続のモジュールの拡張に大きな影響を与えます。

複雑なコンポーネントの分割

モジュールとコンポーネントを分割すると、一部のコンポーネントが非常に複雑になり、Web アプリケーション全体のコードの半分以上を占める場合があります。コンポーネントのこの部分は純粋な js によって実装され、JavaScript モジュール ローダーを使用して読み込まれます。

同じコンポーネントに大量のコードがあると、最終的にはアーキテクチャの破損につながります。したがって、複雑なコンポーネントはさらに分解する必要があります。 Taobao 航空券注文では、乗客情報コンポーネントは複雑なコンポーネントです。次の図に示すように:

一般的に言えば、このような複雑な入力コンポーネントを分割する方法は 2 つあります。

垂直セクション、コンポーネントツリー形式。

コンポーネントをさらに細かい入力コンポーネントに分割し、各入力フィールドを個別のコンポーネントとして扱います。最後に、コンポーネント ツリーが形成されます。

この組織方式は、厳格な構造と明確な階層構造を持ち、フィールドの拡大に容易に対応できるのが最大の利点です。

しかし、次のシナリオを考えてみましょう。ユーザーにできるだけわかりやすくプロンプトを表示するには、入力フィールドの外側のどこかにプロンプ​​ト ヘルプを追加する必要があります。

このシナリオでは、コンポーネント ツリーの構成方法が変更になるたびに少し混乱することになります。各場所に表示されるすべてのヒントを独立したコンポーネントとして扱う必要がありますか?

フィールド レベルの普遍性により、詳細な調整に適応する能力が低下し、その代償としてインターフェイス エクスペリエンスが犠牲になります。

横断的、AOP スタイル。

すべての入力フィールドを抽象的に同じコンポーネントとして扱います。豊富なアプリケーション機能に応じて、コンポーネントをレイヤーで表示します。この例では、乗客コンポーネントは単純なものから複雑なものまで 3 つの側面に分割されています。

側面 1 - 基本的なプレゼンテーション層は、入力と基本的な DOM 管理を完了できる最も基本的なフォーム コントロールのみを担当します。

側面 2 - リッチ プレゼンテーション レイヤーは、ベース レイヤーの基本的な HTML コントロールを変更して、リッチ入力コントロールを形成する役割を担います。

側面 3 - 検証レイヤーは、ベース レイヤーの入力データに対してビジネス レベルの検証を実行する役割を担います。

将来、新しいヒントやその他のビジネス ロジックを追加する場合は、新しい側面を追加するだけで済み、古いコード ファイルを変更する必要はまったくないか、ほとんどありません。

Taobao の航空券注文では AOP アプローチが使用されています。最終的なコード量から判断すると、複雑さがさまざまなファイルに比較的均等に分散されていることがわかります。

同様に、このアプローチにも限界があります。フィールドを拡張する必要がある場合、それは大惨事となり、あらゆる面で変更を加える必要があるかもしれません。

「最適な解決策などなく、最も適した解決策だけがある」という古い格言があります。どのような解決策も、特定のシナリオで判断される必要があります。実際、この問題についてさらに調査すると、次のようなルールが明らかになります。

コンポーネントやモジュールでは、シンプルなデザイン、普遍性(フィールドレベルの拡張性)、インターフェースエクスペリエンスを同時に追求することは不可能です。シナリオがフィールドの柔軟な拡張に適応する必要がある場合は、垂直切断モードを採用する必要があります。使用シナリオでフィールドの決定とより詳細な制御が必要な場合は、横断的な AOP スタイルが使用されます。両方を考慮する場合は、複雑なデザインを導入し、水平切断と垂直切断を総合的に活用する必要があります。ただし、最終的な設計は複雑になり、開発と保守のコストがかかります。

Taobao 航空券などのインターネット アプリケーションの場合、フィールドの数が比較的固定されており、固定された数のフィールドに関する最適化のニーズが無限にあるため、コンポーネントを分割するために横断的アプローチが使用されます。ただし、企業のイントラネット アプリケーションや Web サイトのバックエンド Web アプリケーションでは、フィールドは頻繁に変更されます。主に垂直分割アプローチを採用することをお勧めします。

フォーム検証

フォームがあるところには検証があります。プロジェクトの初期段階では、検証機能は常に重要ではありません。プロジェクトの後半段階を待っていると、検証に膨大な作業負荷がかかり、多数のバグの原因になっていることに気づくことがよくあります。したがって、検証は、過小評価されやすい典型的なタスクですが、膨大な作業量を伴うため、特別な処理と特別な設計が必要です。

一般的に言えば、複雑さに応じて次の 2 つのカテゴリに分けられます。

フォーマットチェック

フォーマット チェックでは通常、ユーザー入力のフォーマットが、数値、電話番号、電子メール アドレスなどの要件を満たしているかどうかを確認します。このタイプの検証は、単一の検証ドメインを特徴としており、通常は 1 つの入力またはコンポーネントの値のみをチェックします。フォーマット検証は、ユーザーに表示される内容に非常に近いものでなければなりません。このような検証情報を HTML タグ属性に直接記述することは、非常に良い方法です。 HTML5 の input の pattern 属性は、この考えに基づいたソリューションです。

論理的検証

論理検証とは、同じユーザー名が存在するか、入力された生年月日がID番号と一致していないかなど、フォーマット検証を満たした後に行われる業務関連の検証です。このタイプの検証には通常、複数の入力フィールドが含まれ、ユーザーの入力内容を包括的に検証する必要があります。このタイプの検証ロジックは複雑であり、HTML での記述には適していません。

検証の問題を解決する、人気のフォーム検証フレームワークは数多くあります。適切な検証フレームワークを導入するには、まず検証プロセスを理解する必要があります。

一般的な検証プロセスは次のとおりです。ユーザーが特定の入力を完了し、フォーカスの喪失やキーアップなどの理由により、特定の瞬間にアプリケーションが検証をトリガーします。トリガーされた検証プロセスは、ここで入力に必要な検証ルールを見つけ (このルールは HTML に直接記述されている場合もあります)、順序が正しいかどうかを判断します。正しい場合は、プロンプトが表示されることがあります。間違っている場合も、プロンプトが表示されることがあります。

上記のシナリオの説明から、検証の重要なリンクがいくつか見つかります。ここでは、経営における古典的な 5w1h 問題分析手法を部分的に使用して問題を分析します。

who: どの入力コントロールのコンテンツを検証する必要があるか。これはフレームワークでは解決できない問題です。どの入力フィールドを検証するかは、アプリケーションによって渡される必要があります。

when: チェックがトリガーされるタイミング。たとえば、「who」がフォーカスを失ったとき。フレームワークが処理するには変更が多すぎます。受動的にのみトリガーできます。

what: どのような検証を行うか。この「what」は HTML で記述されることもあります。基本的に、すべての形式の検証は修正されており、この問題はフレームワーク内で修正されるはずです。ただし、フレームワークでは、より複雑なビジネス検証のためにインターフェースを予約する必要があります。

how: 検証が完了した後に実行されるアクション。フレームワークは、何をすべきかを決定できませんが、検証結果が出た後、フレームワークは外部の呼び出し元に通知できるはずです。

フレームワークを設計するとき、または既存のフレームワークを選択するときに最初に行うべきことは、フレームワークの境界を区別することです。簡単に言えば、何をすべきか、何をすべきでないかということです。フレームワークでは、比較的固定されたビジネス プロセスを実装する必要があります。同時に、可変部分には十分な柔軟性が確保されています。

一般的な検証フレームワークにはインターフェース部分を含めることはできません。インターフェースは変更可能で、列挙するのが困難です。エラーを表示するためにヒントを使用するか、入力フィールドの近くに表示するか、アニメーションが必要かどうか、入力フィールドの視覚的な状態を変更する必要があるかどうかなど、これらの可変部分はフレームワークの外部コンテンツであり、より専門的なヒント コンポーネントまたはポップアップによって補完される必要があります。フレームワークは、検証が完了したときにエラー プロンプトを表示するなど、いくつかの処理を完了するように関連コンポーネントに通知する役割のみを担う必要があります。

上記の分析に基づいて、検証フレームワークには以下の仕様が必要です。

1. 「何」の問題を解決します。電話番号、電子メールなど、さまざまな形式の検証ルールが組み込まれており、新しい論理検証を柔軟に定義できます。

2. 「who」問題を解決する。実際に入力文字に基づいて who に対応する値を見つける方法を説明します。そして、この検証ルールは誰に使えるのか

3. いつの問題を解決します。検証をトリガーするメソッドを提供します。

4. 方法の問題を解決する。検証結果が生成された後、外部の機能フレームワークに通知できます。

Taobao 航空券注文アプリケーションでは、上記の原則に基づいて Validator フレームワークが設計されました。インターフェース定義は次のとおりです。Validator は検証フレームワーク オブジェクトです。

コンストラクターに検証ロジック定義のテーブルを提供します。下図のように、以下の構造を渡して各フィールドに対応した検証方法を定義します。下の図では、各行がフィールドとして定義されています。各フィールドには複数のルールがあります。各ルールは、フレームワークに組み込まれたフォーマット チェック、または実際には関数名であるカスタム ロジック チェックにすることができます。

Validator フレームワークは、validate() メソッドを提供します。validate メソッドには 2 つの動作があります。パラメータが指定されていない場合は、すべてのフィールドが順番に検証され、最終結果が返されます。フィールド名が実行されると、フレームワークはフィールド名に対応する入力フィールドのみを検証します。

検証結果に関係なく、validate() メソッドが実行されると、フレームワークはイベント 'onValidate' をオブザーバーに送信します。後続のアクションをトリガーします。

一部の補助パラメータでは、フィールド名から入力ドメイン値を見つける関数を提供する必要があります。

要約する

複雑なフォームを扱うときは、まずフォームを適切なモジュールとコンポーネントに分割して複雑さを分散させます。次に、詳細なブロードキャスト メカニズムを使用して、分散モジュールとコンポーネント間の通信の問題を解決します。次に、複雑すぎるコンポーネントをさらに分割する必要があります。分割には、特定の使用シナリオに応じて、垂直カットと水平カットの 2 つの方法があります。最後に、検証を過小評価しないでください。検証には特別な処理と特別な設計が必要です。


元のタイトル: タオバオの航空券注文業務と複雑なフォームアプリケーションの分離

キーワード: 複雑、フォーム、アプリケーション、分離、タオバオマシン、チケット注文、単一の実践、背景、ウェブ、ウェブマスター、ウェブサイト、ウェブサイトのプロモーション、収益化

<<:  ブランドをオンライン配信に活用する傾向

>>:  Baidu ニュース: Baidu 検索結果の新たな変更

推薦する

ウェブサイト上のデッドページの管理を強化し、検索エンジンの親和性を向上させる

ウェブサイトの運営期間が長くなるほど、デッドページの規模は大きくなります。このようなデッドページの存...

#ハロウィン# dedipath は全品 50% オフ、米国 10 か所のデータセンター、専用サーバー (最低 39 ドル) + VPS (最低 20 ドル/年) を提供しています

米国のサーバー販売業者 dedipath はハロウィーン プロモーションを開始し、米国の 10 のデ...

mach9servers-$2.66/512m メモリ/1g バースト/20g ハードディスク/2T トラフィック

Mach9servers、私はこのホストをよく知りません。Host Cat にはこれまで登場したこと...

新しいテクノロジーが次々と登場しています。次世代のクラウド コンピューティングのブレークスルーはどこにあるのでしょうか?

今はIT技術が急速に発展している時代です。ハードウェア インフラストラクチャの継続的なアップグレード...

ウェブマスターの道は厳しい、私たちはどこへ向かうのでしょうか?

急速に発展するインターネットの時代に、忘れることのできない、インターネットへの貢献が計り知れない業界...

Xunlei Kankan が kankan.com のドメイン名移行を完了、数百万ドル相当

Xunlei Kankanは9月21日、ネットワーク全体を新しいドメイン名www.kankan.co...

ウェブサイトのソフト記事プロモーションに必要な3つの基本要素

ウェブサイトの SEO 最適化と外部リンクのプロモーションにおいて、ソフト記事のプロモーションは最良...

imidc: 50% 割引、年間 48 ドル、香港 VPS/台湾 VPS、512M メモリ/1 コア/20g SSD/500g トラフィック

imidc は、直接接続の香港 VPS と台湾 VPS (cn2 ネットワーク) を 50% 割引で...

分散ID生成スノーフレークアルゴリズム

一意の ID により、データの一意性を識別できます。分散システムで一意の ID を生成する方法は多数...

dedione - CN2 回線、無制限トラフィック VPS、KVM/1G メモリ/20g ハードディスク

dedione は Hostcat で 3 回紹介されていますが、今回はより優れた CN2 回線、無...

キーワードをホームページに一括で単一リンクプッシュする方法

このテーマで記事を書くのは初めてなので、さらにアドバイスをいただければ幸いです。キーワード、特に比較...

DigitalOcean アカウントの削除に関する注意事項

私は11か月間、何の問題もなくデジタルオーシャンを使用しており、多くの友人に購入を勧めました。問題が...

JD.comがダブル11データを発表:注文量は通常の3倍

新浪科技新聞は11月11日午後、JD.comが一連の最近の販促データを発表した。11月11日午前0時...

ウェブサイト分析の運用分析指標の簡単な分析

2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っています1. 電子...