1756870204
2025-09-03 03:20:00
「木を切り倒すために6時間を与えてください。最初の4つを鋭くします。」 – アブラハム・リンカーン
角度発達の世界では、あなたのプロジェクト構造はそのxです。コーディング機能にまっすぐ飛びたいと思うかもしれませんが、初日に行うアーキテクチャの決定は、開発速度を加速するか、今後何年もチームに出没する技術的な負債を作成します。
あなたの角度アプリケーションは成長している都市と考えてください。明確な地区、効率的な輸送、スケーラブルなインフラストラクチャを備えたよく計画された都市は、何百万人もの住民に対応できます。対照的に、計画なしで有機的に成長した都市は、交通渋滞と都市のスプロールの迷路になります。あなたの角度プロジェクトは同じ選択に直面しています:最初からスケールのためのアーキテクト、または後で価格を支払う。
2つのアーキテクチャの物語
技術的な詳細を深く掘り下げる前に、適切なプロジェクト構造の重要性を示す2つの実際のシナリオを調べてみましょう。
モノリシックな間違い
簡単なeコマースアプリケーションで始まったスタートアップを想像してください。当初、彼らのファイル構造は次のように見えました:
src/
├── app/
│ ├── components/
│ │ ├── header.component.ts
│ │ ├── footer.component.ts
│ │ ├── product-list.component.ts
│ │ ├── product-detail.component.ts
│ │ ├── shopping-cart.component.ts
│ │ └── checkout.component.ts
│ ├── services/
│ │ ├── product.service.ts
│ │ ├── cart.service.ts
│ │ └── user.service.ts
│ └── models/
│ ├── product.model.ts
│ └── user.model.ts
6か月後、ユーザー管理、管理パネル、分析、およびサードパーティの統合を追加した後、その構造は混乱に陥りました。
src/
├── app/
│ ├── components/ (47 components)
│ ├── services/ (23 services)
│ ├── models/ (15 models)
│ ├── pipes/ (8 pipes)
│ ├── directives/ (12 directives)
│ └── guards/ (6 guards)
開発者は、コードを書くよりもファイルの検索に多くの時間を費やしました。コードベースがマーティン・ファウラーが「泥の大きなボール」と呼んでいるものに似ているため、新しい機能を追加することはますます困難になりました – 偶然に構造化された、広大な、ずさんな、ダクトテープとむき出しのワイヤー、スパゲッティコードジャングル。
機能第一のサクセスストーリー
これを、初日から機能ベースのアーキテクチャから始めた別の会社と対照的です。より大きなアプリケーションであっても、それらの構造は清潔で航行可能なままでした:
src/
├── app/
│ ├── core/
│ ├── shared/
│ ├── features/
│ │ ├── products/
│ │ ├── cart/
│ │ ├── user-management/
│ │ ├── admin/
│ │ └── analytics/
│ └── layout/
ボブ・マーティンおじさんが賢く指摘したように: 「ソフトウェアシステムのアーキテクチャは、問題のドメインをチームの理解の証です。」 2番目のチームは、アプリケーションが単なるコードではなく、ビジネスドメインを反映していることを理解していました。
機能ベースとレイヤーベース:基本的な選択
あなたが下す最も重要な建築上の決定は、機能ベースとレイヤーベースの組織を選択することです。この選択は、アプリケーションの構造に関するその後のすべての決定に影響を与えます。
レイヤーベースのアーキテクチャ:従来のアプローチ
レイヤーベースのアーキテクチャは、すべてのコンポーネントを一緒に、すべてのサービス、すべてのモデルを一緒にコンポーネントによってコードを整理します。それは、主題ではなくバインディングタイプによってライブラリを整理するようなものです。
src/app/
├── components/
│ ├── user-profile.component.ts
│ ├── product-list.component.ts
│ └── order-history.component.ts
├── services/
│ ├── user.service.ts
│ ├── product.service.ts
│ └── order.service.ts
└── models/
├── user.model.ts
├── product.model.ts
└── order.model.ts
利点:
- 他のフレームワークから来る開発者に馴染みのある
- 最初は簡単に理解できます
- タイプごとにファイルを簡単に見つけることができます
短所:
- アプリケーションが成長するにつれて扱いにくい
- レイヤー間の高い結合
- 怠zyなロードを実装するのは難しい
- 参照地域の原則に違反します
機能ベースのアーキテクチャ:スケーラブルなソリューション
機能ベースのアーキテクチャは、ビジネスドメインまたは機能ごとにコードを整理します。各機能は、独自のコンポーネント、サービス、モデルを備えた自己完結型モジュールになります。
src/app/
├── core/
│ ├── auth/
│ ├── http-interceptors/
│ └── error-handling/
├── shared/
│ ├── components/
│ ├── directives/
│ ├── pipes/
│ └── models/
├── features/
│ ├── user-management/
│ │ ├── components/
│ │ ├── services/
│ │ ├── models/
│ │ └── user-management.module.ts
│ ├── product-catalog/
│ │ ├── components/
│ │ ├── services/
│ │ ├── models/
│ │ └── product-catalog.module.ts
│ └── order-processing/
│ ├── components/
│ ├── services/
│ ├── models/
│ └── order-processing.module.ts
└── layout/
├── header/
├── sidebar/
└── footer/
このアプローチは、エリック・エヴァンスが「ドメイン駆動型のデザイン」と呼んでいるものに従います。 「ソフトウェアの核心は、ユーザーのドメイン関連の問題を解決する能力です。」
完全な角度アーキテクチャの青写真
例として、複雑なページビルダーアプリケーションを使用して、包括的なプロジェクト構造を構築しましょう。このアプリケーションを使用すると、ユーザーはコンポーネントをドラッグおよびドロップし、コンテンツを管理し、ページを公開することでWebサイトを作成できます。
コアモジュール:基礎
コアモジュールには、一度だけロードする必要があるシングルトンサービスとアプリケーション全体の機能が含まれています。
src/app/core/
├── auth/
│ ├── guards/
│ │ ├── auth.guard.ts
│ │ └── role.guard.ts
│ ├── interceptors/
│ │ ├── auth.interceptor.ts
│ │ └── error.interceptor.ts
│ ├── services/
│ │ ├── auth.service.ts
│ │ └── token.service.ts
│ └── models/
│ ├── user.model.ts
│ └── role.model.ts
├── error-handling/
│ ├── global-error-handler.ts
│ └── error-dialog.component.ts
├── http/
│ ├── api.service.ts
│ └── http-error-handler.service.ts
└── core.module.ts
コアモジュールの実装:
@NgModule({
providers: [
AuthService,
ApiService,
{
provide: ErrorHandler,
useClass: GlobalErrorHandler
},
{
provide: HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi: true
}
]
})
export class CoreModule {
constructor(@Optional() @SkipSelf() parentModule: CoreModule) {
if (parentModule) {
throw new Error('CoreModule is already loaded. Import only once.');
}
}
}
ワード・カニンガムが観察したように: 「あなたが読んだ各ルーチンがあなたが期待していたものであるとき、あなたはクリーンコードを使用していることを知っています。」 コアモジュールには、その名前が示唆するもの、つまり他のすべてが依存するコア機能を正確に含める必要があります。
共有モジュール:一般的なツールキット
共有モジュールには、複数の機能で使用できる再利用可能なコンポーネント、パイプ、および指令が含まれています。
src/app/shared/
├── components/
│ ├── ui/
│ │ ├── button/
│ │ │ ├── button.component.ts
│ │ │ ├── button.component.html
│ │ │ ├── button.component.scss
│ │ │ └── button.component.spec.ts
│ │ ├── modal/
│ │ └── loading-spinner/
│ ├── forms/
│ │ ├── dynamic-form/
│ │ └── validation-message/
│ └── data-display/
│ ├── data-table/
│ └── pagination/
├── directives/
│ ├── click-outside.directive.ts
│ └── lazy-load.directive.ts
├── pipes/
│ ├── safe-html.pipe.ts
│ └── truncate.pipe.ts
├── models/
│ ├── api-response.model.ts
│ └── paginated-result.model.ts
├── utils/
│ ├── validators.ts
│ └── date-helpers.ts
└── shared.module.ts
#角度プロジェクト構造初日からのスケールのための構築 #Saurabh #Singh #9月2025年