プロジェクトロジックの実装 - テクノロジー
コンテンツにスキップ

プロジェクトロジックの実装

広告

実装アプローチの哲学

ウォーターフォールアプローチ

アプリケーションを実装するためのウォーターフォール アプローチでは、設計者がエンド ユーザー組織の 1 人以上の代表者と相談し、すべてのアプリケーション仕様を書き留める必要があります。通常、仕様は一連の機能文書またはユースケースで構成されており、エンドユーザーが文書を簡単に読んで理解できるように書かれています。

エンド ユーザーがこれらのドキュメントに署名すると、アプリケーションを設計する技術設計チームによってドキュメントが収集され、クラス モデル図、状態図、アクティビティ図、データ モデルなどのさまざまな成果物が作成されます。このフェーズの目標は、開発者が問題なく必要なコードを作成できるように、すべてを詳細に記述することです。設計は開発チームとテスト チームに正式に引き渡されます。納品後、開発チームはコーディングを開始し、テスト チームは技術設計をユース ケースと組み合わせて使用して、テスト ケースとテスト シナリオを作成します。

開発チームがコーディングを完了すると、コードはテスト チームに引き渡されます。テスト チームは、要件と詳細な設計に基づいて設計したテストを実行します。問題がある場合は開発チームによって修正されます。テストと修復プロセスが完了すると、アプリケーションは受け入れテストのためにエンド ユーザーに引き渡されます。エンド ユーザーは、アプリケーションが初期要件に準拠しているかどうかを確認する最終チェックを実行します。承認された場合は完成品を承認し、プロジェクトが完了します。開発チームがコーディングを完了すると、コードはテスト チームに引き渡されます。

テスト チームは、要件と詳細な設計に基づいて設計したテストを実行します。問題がある場合は開発チームによって修正されます。テストと修復プロセスが完了すると、アプリケーションは受け入れテストのためにエンド ユーザーに引き渡されます。エンド ユーザーは、アプリケーションが初期要件に準拠しているかどうかを確認する最終チェックを実行します。承認された場合は完成品を承認し、プロジェクトが完了します。開発チームがコーディングを完了すると、コードはテスト チームに引き渡されます。テスト チームは、要件と詳細な設計に基づいて設計したテストを実行します。

 問題がある場合は開発チームによって修正されます。テストと修復プロセスが完了すると、アプリケーションは受け入れテストのためにエンド ユーザーに引き渡されます。エンド ユーザーは、アプリケーションが初期要件に準拠しているかどうかを確認する最終チェックを実行します。承認された場合は完成品を承認し、プロジェクトが完了します。

エンド ユーザーは、アプリケーションが初期要件に準拠しているかどうかを確認する最終チェックを実行します。承認された場合は完成品を承認し、プロジェクトが完了します。エンド ユーザーは、アプリケーションが初期要件に準拠しているかどうかを確認する最終チェックを実行します。承認された場合は完成品を承認し、プロジェクトが完了します。

ウォーターフォール アプローチを使用する場合、プロジェクトには多かれ少なかれフェーズを含めることができますが、主な特徴は、各フェーズの始まりと終わりが非常に形式的に行われ、成果物が非常に形式的になることです。

ウォーターフォール アプローチの利点は、各フェーズを担当するチームの責任が大きくなることです。何を、いつ、誰に届ける必要があるかは明確です。多くの場合、開発チームはユーザーと対話する必要はありません。これは、開発を別の国にアウトソーシングする場合に非常に役立ちます。

ウォーターフォール アプローチの主な欠点は、すべてが非常に形式的な方法で組織されている環境では、変更に対応する柔軟性が低下することです。引っ越しでも整理が必要です。これを効果的に行っている企業はほとんどないようで、多くの場合間接費が大幅に増加します。プロジェクトのコストを管理するために、アプリケーションの最初の納品まで要件の変更を遅らせ、事実上、エンド ユーザーのニーズを満たさないアプリケーションを納品する企業もあります。

アジャイル開発

長期にわたるソフトウェア開発プロジェクトの多くは予算を超過し、製品を期限までに納品できませんでした。アジャイル ソフトウェア開発哲学の前提は、通常 1 ~ 4 週間かかるイテレーションと呼ばれる短期間でソフトウェアを開発することでリスクを最小限に抑えることです。各イテレーションは、独自のミニチュア ソフトウェア プロジェクトのようなもので、計画、要件分析、設計、コーディング、テスト、ドキュメントなど、新しい機能の増分をリリースするために必要なすべてのタスクが含まれます。反復では製品リリースを保証するのに十分な機能が追加されない可能性がありますが、アジャイル ソフトウェア プロジェクトは、各反復の終了時に新しいソフトウェアをリリースできることを目指しています。各反復の終わりに、チームはプロジェクトの優先順位を再評価します。

アジャイル ソフトウェア開発の目標は、有用なソフトウェアを迅速かつ継続的に提供することで顧客満足度を達成することです。常にクライアントが必要とするものを構築することを目指しています。要件の後期変更に反対するのではなく、歓迎する。変化する状況に定期的に適応する。起業家と開発者は日常的に緊密に協力しており、対面での会話が最良のコミュニケーション形態です。

アジャイル ソフトウェア開発の主な利点は、常にビジネス ニーズに従って提供することを目指し、変化に柔軟に対応できることです。もちろん、欠点は、範囲、計画、予算編成の管理が複雑になることです。もう 1 つの一般的なリスクは、(技術的な) ドキュメントへの注意が限定されていることです。

段階的な開発

インクリメンタル ソフトウェア開発は、アジャイル開発とウォーターフォール開発を組み合わせたものです。アプリケーションは段階的に設計、実装、テストされるため、各段階でエンド ユーザーに配信できます。プロジェクトは、最後の増分が完了するまで完了しません。中間の増分を定義し、アジャイル開発の利点のいくつかを利用することで、ウォーターフォールを短縮することを目的としています。前回の増分で受け取ったフィードバックに基づいて、次の増分を提供するときに調整を行うことができます。次の増分は、新しいコードだけでなく、以前に提供されたコードへの変更も含めることができます。

利点は、手続きはそのままですが、変更管理が容易になることです。アプリケーションのテストとデプロイを複数回行うコストは、1 回だけ行う場合よりも高くなります。

プログラムフロー制御

プログラム フロー制御へのアプローチの選択は、非常に構造的なタスクです。目標は、機能とコードの追加を開始すると、すべてが独自の場所を持っているように見えるアプリケーションのブループリントを作成することです。高品質のコードをレビューしたり書いたりしたことがあるなら、この原則を理解しているでしょう。

コードの編成

プログラム フローを設計する最初のステップは、コードを整理し、アプリケーションの計画または概要を作成するのに役立つ一連のルールを確立することです。コードが 1 つの論理的な場所に配置されているため、メンテナンス、デバッグ、バグ修正がより簡単に実行できます。基礎作業が完了したら、アプリケーション ロジックを実装するアプローチを選択できます。

デザイン パターンは、プログラム フロー制御の設計において重要な役割を果たす必要があります。長年にわたり、多くのコードが作成され、繰り返し発生する問題に対して多くのソリューションが設計されてきました。これらのソリューションはデザイン パターンで確立されます。一般的なソフトウェア設計の問題に設計パターンを適用すると、容易に認識でき、同僚が実装できるソリューションを作成するのに役立ちます。固有の問題には固有の解決策が必要ですが、デザイン パターンを使用して問題を解決することができます。

プロジェクトの作成

レイヤー

最初のステップは、論理層を検討することです。レイヤーはレイヤーとは同じではなく、しばしば混同されたり、同じであると考えられたりする場合があることに注意してください。

レイヤーとレイヤー

レイヤーとは、コード内に境界を作成することです。最上位層は下位層のコードへの参照を持つことができますが、層が上位層のコードへの参照を持つことはできません。レイヤ化は、複数のコンピュータにわたるレイヤの物理的な分散に関係します。たとえば、3 層アプリケーションでは、ユーザー インターフェイスはデスクトップ コンピューターで実行するように設計され、アプリケーション ロジックはアプリケーション サーバーで実行するように設計され、データベースはデータベース サーバーで実行するように設計されています。専用データ層とそのコード各レイヤーは複数のレイヤーで構成できます。

図 8-1: 基本的な 3 層組織

レイヤーとは抽象化のレベルを指します。図 8-1 に示す層は、ほとんどのアプリケーションに当てはまります。これらのレベルは 3 つの主要なレイヤーとも呼ばれ、他の名前がいくつかある場合があります。原則として、プレゼンテーション層のコードはアプリケーション論理層のサービスを呼び出すことができますが、アプリケーション論理層はプレゼンテーション層のメソッドを呼び出してはなりません。プレゼンテーション層は、アプリケーション ロジック層によって実装された責任を回避することになるため、データ アクセス層を直接呼び出すことはできません。データ アクセス層はアプリケーション ロジック層を決して呼び出さないでください。

レイヤーは単なる抽象化であり、おそらくレイヤーを実装する最も簡単な方法は、プロジェクト内にフォルダーを作成し、適切なフォルダーにコードを追加することです。より便利なアプローチは、各レイヤーを別個のプロジェクトに配置し、別個のアセンブリを作成することです。アプリケーション ロジックをライブラリ アセンブリに配置する利点は、Microsoft Visual Studio または NUnit を使用して単体テストを作成し、ロジックをテストできることです。また、各レイヤーを展開する場所を選択する際の柔軟性も生まれます。

物理層

エンタープライズ アプリケーションでは、同じロジックに対して複数のクライアントが存在することが想定されます。実際、アプリケーションがエンタープライズ アプリケーションである理由は、アプリケーションがクライアント、アプリケーション サーバー、データベース サーバーの 3 つの層で展開されることです。会社の営業部門が作成した Microsoft Office Access アプリケーションは、営業部門にとって非常に重要ですが、エンタープライズ アプリケーションを構成しません。

多くの場合、アプリケーション ロジック層とデータ アクセス層はアプリケーション サーバー上に一緒にデプロイされることに注意してください。プロジェクトの設計の一部として、.NET または Web リモート サービスを使用してアプリケーション サーバーにアクセスするかどうかを選択します。選択に関係なく、プレゼンテーション層のリモート サービスに簡単にアクセスするためのコードを追加します。 Web サービスを使用してアプリケーション サーバー上のサービスにアクセスしている場合、Visual Studio .NET が作業を行ってプロキシ コードを生成し、リモート プロキシ パターンの実装を自動的に提供します。

レイヤーにパターンを追加する

3 つの基本レイヤーは、高レベルの概要を提供します。いくつかの構造パターンを追加して、堅牢なエンタープライズ アーキテクチャを作成しましょう。結果を図 8-2 に示します。

アプリケーション ロジック層に焦点を当てます。図 8-2 は、アプリケーション ロジックへのアクセスにファサード パターンが使用されていることを示しています。ファサードは、クラス ライブラリなどのより大きなコード本体への簡素化されたインターフェイスを提供するオブジェクトです。ほとんどのコードがファサードを使用するため、ファサードを使用すると、ライブラリの内部動作に対する外部コードの依存関係が軽減され、システム開発の柔軟性が向上します。これを行うために、ファサードは、きめの細かいオブジェクトのコレクションに対して、きめの粗いインターフェイスを提供します。

意思決定の流れ

プログラム フロー制御は意思決定フローとも呼ばれ、アプリケーション ロジック層でサービスを設計する方法、または前の段落で見たようにファサードでメソッドを設計する方法に関係します。

サービスを整理するには 2 つのアプローチがあります。

  • アクション指向
  • 国家指向

行動指向のアプローチ

ユーザーのアクションに基づいてサービスを編成することにより、プレゼンテーション層からの特定のリクエストをそれぞれ処理するサービスを提供することでアプリケーション ロジックを実装することになります。これは、トランザクション スクリプト パターンとも呼ばれます。このアプローチはシンプルで非常に自然に感じられるため人気があります。このアプローチに従うメソッドの例としては、BookStoreService.AddNewOrder(Order order) および BookStoreService.CancelOrder(int orderId) があります。

アクションの実行に必要なロジックはメソッド内で非常に順番に実装されるため、非常に読みやすくなりますが、コードの再利用はより困難になります。テーブル モジュール パターンなどの追加のデザイン パターンを使用すると、再利用性を高めることができます。

国家指向のアプローチ

より状態指向的な方法でアプリケーションの意思決定フローを実装することも可能です。アプリケーション サーバーによって提供されるサービスは、BookStoreService.SaveOrder(Order order) など、本質的により汎用的なものです。このメソッドは注文ステータスを確認し、新しい注文を追加するか既存の注文をキャンセルするかを決定します。

データ構造プロジェクト

データ構造を設計する際には、いくつかの選択を行う必要があります。最初の選択はデータ ストレージ メカニズム、2 番目はデータの使用目的、3 番目はバージョン管理の要件です。データ構造の設計を検討するには 3 つの方法があります。

  • サービスはデータを提供します。データはリレーショナル データベースを反映したものです。
  • データはオブジェクトにマッピングされ、サービスはオブジェクトへのアクセスを提供する必要があります。
  • サービスによって提供されるデータはスキーマベースである必要があります。

データ フロー構造の基礎として 3 つのうちの 1 つを選択することは、設計プロセスの早い段階で行う必要があります。多くの企業は、すべてのプロジェクトで 3 つのオプションのいずれかを義務付ける会社方針を持っていますが、可能であれば、各プロジェクトのオプションを再評価し、当面のプロジェクトに最適なアプローチを選択する必要があります。

データ ストレージ エンジンの選択

アプリケーションを設計するときは、間違いなく、何らかのタイプのデータ ストレージを設計する必要があります。次のストアとデータ ストレージ形式が利用可能です。

  • 記録
  • app.config ファイル
  • XMLファイル
  • プレーンテキストファイル
  • データベース
  • メッセージキューイング

各店舗には独自の特徴があり、特定の要件に合わせてカスタマイズできます。

データフローの設計

ADO.NETを使用したデータフロー

アプリケーション ロジック層にデータ中心のサービスを実装する場合は、ADO.NET を使用してデータ フローを設計します。 .NET Framework クラス ライブラリは、マネージ コードでデータを操作するための広範なアプリケーション プログラミング インターフェイス (API) を提供します。 ADO.NET と呼ばれるこの API は、System.Data 名前空間にあります。メディア ストアとデータ ストアの完全な分離は、ADO.NET の重要な設計機能です。 DataSet、DataTable、DataRow などのクラスはデータを保存するように設計されていますが、データの出所に関する情報は保持しません。これらはデータ ソースに依存しないと見なされます。 SqlConnection、SqlDataAdapter、SqlCommand などの別のクラスのセットが、データ ソースへの接続、データの取得、DataSet、DataTable、DataRow への設定を処理します。これらのクラスは、System.Data.Sql、System.Data.OleDB、System.Data.Oracle などのサブ名前空間にあります。接続するデータ ソースに応じて、適切な名前空間のクラスを使用できます。また、使用している製品の範囲に応じて、これらのクラスが提供する機能が多かれ少なかれ異なることがわかります。

DataSet はデータ ソースに接続されていないため、アプリケーション内のデータ フローを管理するために非常にうまく使用できます。図 8-5 は、これを行うときのデータ フローを示しています。

このプロジェクトを見て、誰かがあなたの書店にログインして 3 冊の本を注文したと想像してみましょう。プレゼンテーション層はショッピングカートの状態を管理します。顧客は注文する準備ができており、必要なデータをすべて提供しています。彼は命令を送ることを選択しました。 Web ページは、すべてのデータを、注文用と注文用の 2 つの DataTable を含む DataSet に変換します。リクエストの DataRow を挿入します。そして、注文明細行に 3 つの DataRow を挿入します。その後、Web ページはこのデータをもう一度ユーザーに表示し、DataSet に対するデータ バインディングを制御して、「よろしいですか?」と尋ねます。ユーザーがリクエストを確認すると、リクエストはアプリケーションの論理層に送信されます。アプリケーション ロジック層は、DataSet をチェックしてすべての必須フィールドに値があるかどうかを確認し、ユーザーの値が US$ 1,000 を超えているかどうかを確認します。未払いの請求書には 00。すべてが正常であれば、DataSet はデータ アクセス層に渡され、データベースに接続され、DataSet 情報に基づいて挿入命令が生成されます。

この方法で DataSet を使用すると、アプリケーションを作成し、フレームワーク クラス ライブラリの機能と、DataSet に対する GridView などの複数のコントロールにデータをバインドする ASP.NET の機能を利用するための迅速かつ効率的な方法です。単純な DataSet オブジェクトを使用する代わりに、Typed DataSet オブジェクトを使用し、アプリケーション ロジック層だけでなくプレゼンテーション層にもコードを実装することでコーディング エクスペリエンスを向上させることができます。このアプローチの利点は、このアプローチの欠点でもあります。データ モデルへの小さな変更は、必ずしも多くのメソッドのシグネチャを変更する必要があるとは限りません。したがって、メンテナンスの面では、これは非常にうまく機能します。プレゼンテーション層は必ずしもユーザー インターフェイスである必要はなく、Web サービスである場合もあることを覚えておいてください。また、データベース内のフィールドの名前を変更するなどの理由で DataSet 定義を変更すると、そのデータを保証するコントラクトを変更することになります。ご想像のとおり、これは重大な問題を引き起こす可能性があります。このシナリオは、プレゼンテーション層が単なるユーザー インターフェイスである場合にはうまく機能しますが、外部システムまたはコンポーネントへのインターフェイスの場合は、アプリケーションの内部動作を非表示にし、データをデータ モデルの直接のクローン以外のものに変換する必要があります。データ転送オブジェクト (DTO) を作成するとよいでしょう。

オブジェクト リレーショナル マッピングを使用したデータ フロー

ADO.NET を使用したデータ フローは、データ フローを管理するための非常にデータ中心のアプローチです。データとロジックは離散的です。スペクトルの反対側では、よりオブジェクト指向のアプローチが採用されています。ここでは、データと動作をグループ化するためにクラスが作成されます。目標は、アプリケーションが作成されたビジネス ドメインで見つかったデータと動作を模倣するクラスを定義することです。結果は、多くの場合、ビジネス オブジェクトと呼ばれます。アプリケーションを構成するビジネス オブジェクトの集合はドメイン モデルと呼ばれます。開発者の中には、より複雑なロジックを設計するにはリッチ ドメイン モデルの方が適していると主張する人もいます。そのような声明を証明または反証することは困難です。あなたには選択肢があり、それを選択するのはあなた次第であることを知ってください。

図 8-6 は、図 8-5 と同様のデータ フローを示していますが、オブジェクト リレーショナル マッピング層を追加し、DataSet オブジェクトを別のデータ キャリアに置き換えている点が異なります。

ここで、前と同じことを段階的に実行します。誰かがあなたの書店にログインして 3 冊の本を注文したと想像してください。プレゼンテーション層はショッピングカートの状態を管理します。顧客は注文する準備ができており、必要なデータをすべて提供しています。彼は命令を送ることを選択しました。 Web ページはすべてのデータを DTO に変換し、1 つの注文と 3 つの注文明細のデータを保持し、必要に応じてオブジェクトを作成します。 Web ページはこのデータをユーザーに再度表示し、ASP.NET 2.0 の ObjectDataSource を使用して DTO に対するデータ バインディング コントロールを実行し、「よろしいですか?」と尋ねます。ユーザーが選択を確認すると、DTO がアプリケーションの論理層に送信されます。アプリケーション ロジック層は、DTO を、3 つの OrderLine オブジェクトを含むプロパティを持つ Order タイプのビジネス オブジェクトに変換します。注文方法。 Validate() を呼び出して注文を検証し、すべての必須フィールドに値があるかどうかをチェックし、ユーザーの未払い請求書が R$ 1,000.00 を超えるかどうかを識別するためにチェックが行われます。これを行うために、注文は Order.Customer.GetOutstandingBills() を呼び出します。すべてが正常であれば、Order.Save() メソッドが呼び出されます。注文はオブジェクト リレーショナル マッピング レイヤーに送信され、そこで注文と注文明細行が DataSet 内の DataTable にマップされ、DataSet がデータ アクセス レイヤーに渡されます。データ アクセス レイヤーはデータベースに接続し、その情報から挿入命令を生成します。データセット。もちろん、オブジェクト リレーショナル マッピングを行う方法は数多くありますが、そのすべてに DataSet への変換が含まれるわけではありません。挿入ステートメントを直接作成する場合もありますが、そのステートメントを実行するためにデータ アクセス レイヤーを使用する場合もあります。

ご覧のとおり、いくつかの変換が発生します。ビジネス オブジェクトは動作を実装しており、動作は変更される可能性があるため、DTO の使用が必要です。プレゼンテーション層に対するこれらの変更の影響を最小限に抑えるには、データをビジネス オブジェクトからデータ転送オブジェクトに変換する必要があります。 Java では、データ転送オブジェクトは通常、値オブジェクトと呼ばれます。

ビジネス オブジェクトを操作する大きな利点は、コードの整理に非常に役立つことです。複雑なロジックを振り返ってみると、配管コードがほとんどないため、通常は非常に読みやすくなります。欠点は、ほとんどのデータ ストアが依然としてリレーショナルであり、ビジネス オブジェクトとリレーショナル データのマッピングが非常に複雑になる可能性があることです。

スキーマベースのサービス

データ フローの管理に関しては、2 つの相反するものを見てきました。多くのバリエーションが可能です。一般的なのは、データ ストレージの基本的なユーザー インターフェイス データ サポートとしてデータセットが使用されますが、他のシステムから呼び出される Web サービスには別のスキーマ (DTO) が使用されるバリアントです。アプリケーション層は、リレーショナル データを事前定義されたスキーマに変換します。この主な利点は、サービスを参照するアプリケーションがコンポーネントの内部実装の種類に依存しないことです。これにより、バージョン管理の柔軟性、インターフェイスの下位互換性、およびサービス インターフェイスを変更せずにコンポーネントの実装を変更できる機能が可能になります。

もちろん、Web アプリケーションでビジネス オブジェクトを使用して DTO 変換をバイパスすることもできますが、これは通常、アプリケーション ロジックが Web アプリケーションとともに実装されている場合にのみうまく機能します。データベース接続。これが望ましいかどうかはあなた、そしておそらくあなたのセキュリティ責任者次第です。