多くの開発者は、アプリケーションのサイズが大きくなるとすぐに、アプリケーションのコードベースの整理に苦労しています。 最近、角度とjavascriptの両方のアプリケーションでこれを観察しましたが、歴史的にこの問題は、Javaや過去に使用した多くのflexアプリケーションを含むあらゆる技術に固有のものです。
一般的な傾向は、タイプ別にエンティティを整理することに執着しています。 彼女は、人々が服を並べる方法に驚くほど似ています。
床の上の山
アプリケーションを作成するための公式の出発点であるAngularテンプレートプロジェクトを見てみましょう。 appディレクトリの構造は次のとおりです。
- css /
- img /
- js /
- app.js
- controllers.js
- directives.js
- filters.js
- services.js
- lib /
- パーシャル/
javascriptディレクトリには、記述されたオブジェクトのタイプごとに1つのファイルが含まれています。 衣服を床に重ねて整理することに非常に似ています。 靴下、下着、シャツ、ズボンなどの山があります。 あなたは黒いウールの靴下が山の隅にあることを知っていますが、掘り出すには時間がかかります。
これは混乱です。 人々はこのように生きるべきではなく、開発者はそのようなコードをサポートすべきではありません。 コントローラーとサービスの数が10を超えるとすぐに、ファイル構造が扱いにくくなります。オブジェクトを見つけるのが難しくなり、コントロールのソースの変更のファイルが不透明になります。
ソックスボックス
Javascript組織の次の論理的な部分には、いくつかのエンティティのディレクトリを作成し、オブジェクトを個別のファイルに分割することが含まれます。 服の比phorを続けて、マホガニーの引き出しのチェストを取り、靴下をある引き出しに、下着を別の引き出しに入れ、ズボンとシャツを残りの上に注意深く配置します。
ログインフォーム、製品カタログ、ショッピングカートインターフェイスを備えたシンプルなeコマースサイトを作成しているとします。 また、モデル(ビジネスロジックと状態)およびサービス(HTTP / JSON端末のプロキシ)の新しいエンティティを定義し、それらを「サービス」の1つのヒープにダンプしませんでした。 javascriptディレクトリは次のようになります。
- コントローラー/
- LoginController.js
- RegistrationController.js
- ProductDetailController.js
- SearchResultsController.js
- directives.js
- filters.js
- モデル/
- CartModel.js
- ProductModel.js
- SearchResultsModel.js
- UserModel.js
- サービス/
- CartService.js
- UserService.js
- ProductService.js
いいね! オブジェクトがレイアウトされ、ファイルツリーを表示したり、ホットキーを使用してファイルツリー内を移動したりしやすくなりました。 変更リストで、どの変更が行われたかなどを簡単に示すことができるようになりました。 これは主要な改善点の1つですが、まだいくつかの制限があります。
あなたがオフィスにいて、ドライクリーニングのために明日の朝の出張に必要ないくつかの服装を含める必要があることを想像してください。 家に電話して、ソウルメイトに黒と青の縞模様のスーツをドライクリーナーに連れて行くように頼みます。 そして、黒い飾りのネクタイが付いたグレーのシャツと、単調な黄色のネクタイが付いた白いシャツを忘れないでください。 あなたのソウルメイトがあなたのドレッサーとクローゼットで何が起こっているかに完全になじみがないと想像してください。 ネクタイで引き出しを開くと、黄色のネクタイが3つ表示されます。 どちらを選ぶべきですか?
あなたの服がすぐに衣装にまとめられたら悪いことではないでしょうか? 実際には、現実の世界で衣服を使用してこれを行うことを妨げるコストやスペースなどの制限がありますが、完全に無料のコードで同様のことができます。
モジュール性
ありふれた比theがあまりにも退屈ではないことを期待しましょう。ここに要約があります。
- チームの新しい開発者は、アプリケーションの多くの画面の1つでバグを修正するように依頼されました。
- ディレクトリ構造をかき集めている開発者は、すべてのコントローラー、モデル、およびサービスがきちんと整理されていることを確認します。 残念ながら、これは、どのオブジェクトがどのように相互に関連しているかについて彼に何も伝えません。
- ある時点で開発者がコードの一部を再利用したい場合、別のフォルダーからファイルをレーキする必要があり、必然的に別のフォルダーからコードを取得することを忘れます。
信じられないかもしれませんが、作成する新しいレポートアプリケーションでeコマースアプリケーションのすべてのコントローラーを再利用する必要はほとんどありません。 ただし、認証ロジックの一部を再利用する必要がある場合があります。 これがすべて1か所にあるといいでしょうか? 機能分野に基づいてアプリケーションを再編成しましょう。
- カート/
- CartModel.js
- CartService.js
- 共通/
- directives.js
- filters.js
- 製品/
- 検索/
- SearchResultsController.js
- SearchResultsModel.js
- ProductDetailController.js
- ProductModel.js
- ProductService.js
- 検索/
- ユーザー/
- LoginController.js
- RegistrationController.js
- UserModel.js
- UserService.js
これで、サードパーティの開発者はトップレベルのフォルダーを開き、アプリケーションの動作をすぐに理解できます。 1つのフォルダー内のオブジェクトは互いに関連しており、一部のオブジェクトは他のフォルダーに依存しています。 承認および登録プロセスの仕組みを理解するには、このフォルダー内のファイルを表示するだけです。 コピー/貼り付けを使用したプリミティブな再利用手順は、少なくともフォルダを別のプロジェクトにコピーすることで実行できます。
Angularでは、このステップを基礎として、適切なコードを使用してモジュールを作成できます。
var userModule = angular.module('userModule',[]); userModule.factory('userService', ['$http', function($http) { return new UserService($http); }]); userModule.factory('userModel', ['userService', function(userService) { return new UserModel(userService); }]); userModule.controller('loginController', ['$scope', 'userModel', LoginController]); userModule.controller('registrationController', ['$scope', 'userModel', RegistrationController]);
その後、UserModule.jsをユーザーフォルダーに配置すると、このモジュールで使用される「明示的な」オブジェクトになります。 また、RequireJSまたはBrowserifyローダーにいくつかのディレクティブを追加することも賢明です。
一般的なコードのヒント
各アプリケーションには、多くのモジュールで使用される共通のコードがあります。 そのための場所が必要なだけです。これは、「common」または「shared」などの名前のフォルダーにすることができます。 本当に大規模なアプリケーションでは、機能が部分的に重複および重複する傾向があります。 これらすべてを管理するには、いくつかの方法があります。
- モジュールのオブジェクトが複数の「共通」オブジェクトに直接アクセスする必要がある場合は、それらのオブジェクトに対して1つ以上のファサードを作成します。 これにより、各オブジェクトの寄生虫の数を減らすことができます。これは、通常、寄生虫が多すぎると、コードが腐敗していることを示しているためです。
- 「一般」フォルダが大きなモジュールになった場合、サブモジュールに分割して、特定の機能的なタスクや問題を解決します。 アプリケーションモジュールが必要とする「汎用」モジュールのみを使用するようにします。 これは、SOLIDの「 インターフェース分離の原理 」です。
- 子領域で使用できるように、ユーティリティメソッドを$ rootScopeに追加します。 これにより、アプリケーション内の各コントローラーに同じ依存関係(たとえば、「PermissionsModel」)を注入する必要がなくなります。 これは、グローバルレルムの乱雑さを回避し、依存関係を明確にしないために、慎重に行う必要があることに注意してください。
- イベントを使用して、相互に明示的な参照を必要としないコンポーネントを分離します。 Angularでは、これはオブジェクトのスコープ内のメソッドで$ emit 、 $ broadcast、および$を使用して行われます。 コントローラーは、特定のアクションを実行するイベントを生成し、アクションが完了したという通知を受け取ることができます。
リソースとテストに関する簡単なメモ
HTML、CSS、画像の編成により柔軟にアプローチできると思います。 それらをモジュールフォルダーにネストされた「アセット」フォルダーに配置することで、リソースとそれらに依存するモジュールのバランスが改善される可能性があり、構造が面倒になりません。 また、最上位のフォルダーを、アプリケーションパッケージの構造を反映するフォルダー構造を含むコンテンツフォルダーに分割するのが賢明だと思います。 これはテストにも同じくらい良いと思います。