web-dev-qa-db-ja.com

ソースツリーをどのように整理すればよいですか?

私は個人的な開発者であり、主にWebプロジェクト(W/LAMP)に取り組んでおり、時には平均的な規模のC/C++(非GUI)プロジェクトにも取り組んでいます。

ソースコードツリーの構造化に苦労することがよくあります。実際、通常、私はツリー全体をダンプし、ピースを3〜4回再配置せずにプロジェクトを完了することはありません。これは本当に多くの労力を要し、さらに最終結果は妥協のように見えます。

時々、私はソースの過剰な分類に終わることがあります-フォルダーとサブフォルダーの非常に長いツリー。他の場合では、私は単純にすべてのファイルを特定のフォルダーに集中させ、それらが果たすより大きな目的に基づいて、ソース内の「無秩序な」フォルダーを導きます。

私は尋ねたいと思います:

  • ソースツリーの構造化に役立つ原則/ロジック/ベストプラクティスはありますか?
  • プロジェクトの分析に基づいてソースツリーを事前に視覚化するのに役立つグラフィカル/図式手法(たとえば、データフローの場合はDFD)はありますか?
  • プロジェクトに関連するマルチメディアファイルツリーを構造化するために採用する戦略は何ですか?

バウンティについて:メンバーが独自の慣行を共有している既存の回答に感謝しますが、より一般的で有益な回答(またはリソース)とメンバーからのより多くの応答を奨励したいと思います。

91
check123

ソースツリーのレイアウトはアーキテクチャを反映する必要があります。当然のことながら、適切に構造化されたアーキテクチャは、適切に構造化されたソースツリーレイアウトにつながる可能性があります。 POSA1レイヤーパターン を読んで、アーキテクチャをレイヤー構造に適合させ、結果の各レイヤーに名前を付け、それをソース階層の基礎として使用することをお勧めします。一般的な 層アーキテクチャ をベースラインとして使用:

  • presentation/webService(ビジネスロジックへのWebサービスインターフェイスを提供します)
  • logic/*(ビジネスロジックモジュールはここにあります)
  • storage/sql(ここではバックエンドストレージAPI-これはSQLインターフェースを使用してデータベースに保存します)
  • util/*(ユーティリティコード-​​他のすべてのレイヤーで使用可能ですが、utilの外部を参照しないため、ここに移動します)

レイヤーにはコードが直接含まれているのではなく、モジュールの編成に厳密に使用されていることに注意してください。

モジュール内では、次のようなレイアウトを使用します。

  • <module>(モジュールへの直接パス。モジュール式インターフェースを定義します)
  • <module>/impl/<implName>(モジュール式インターフェースの特定の実装)
  • <module>/doc(モジュールを使用するためのドキュメント)
  • <module>/tb(モジュールの単体テストコード)

どこ <module>は、所属するレイヤーに応じてリポジトリに配置されます。

25
Aidan Cully

私は実際にはwebprojectsに関連する多くのアドバイスを与えることはできませんが、プログラミングプロジェクトでツリーを構造化する方法を次に示します(主にC/C++の観点から):

  • /
    • src —自分で作成したソースファイル
    • ext —サードパーティのライブラリが含まれています
      • libname-1.2.8
        • include —ヘッダー
        • lib —コンパイルされたlibファイル
        • Donwload.txt —使用されているバージョンをダウンロードするためのリンクが含まれています
    • ide —プロジェクトファイルをここに保存します
      • vc1 — IDEに応じてプロジェクトファイルを配置します
    • bin —コンパイルされたexeがここに入ります
    • build —コンパイラのビルドファイル
    • doc —あらゆる種類のドキュメント
    • README
    • インストール
    • コピー

いくつかのメモ:

  1. ライブラリを作成している場合(およびC/C++を使用している場合)、最初にソースファイルを「include」と「src」という2つのフォルダーに整理し、次にモジュール別に整理します。アプリケーションの場合は、モジュールごとに整理します(ヘッダーとソースは同じフォルダーに配置されます)。

  2. 上記のitalicsに記載したファイルとディレクトリは、コードリポジトリに追加しません。

49
Paul

Maven標準ディレクトリレイアウト はJavaに固有の種類で​​すが、他のタイプのプロジェクトの優れた基礎としても役立つ場合があります。

基本的な構造は次のとおりです(「Java」ディレクトリを「php」、「cpp」などに置き換えることができます)。

src/main/Java       Application/Library sources 
src/main/resources  Application/Library resources  
src/main/filters    Resource filter files 
src/main/Assembly   Assembly descriptors 
src/main/config     Configuration files 
src/main/webapp     Web application sources 
src/test/Java       Test sources 
src/test/resources  Test resources 
src/test/filters    Test resource filter files 
src/site            Site 
LICENSE.txt         Project's license 
NOTICE.txt          Notices and attributions required by libraries
README.txt          Project's readme

構造は基本的に「src/main」と「src/test」に分類され、タイプごとにグループ化されます。

15
Michal Miller

理想的には、組織には単一のリポジトリーがあり、その構造は、エンジニアリングとビジネス間の関与を高め、再利用を促進することを目的としています。

...\products\
...\products\productName\
...\products\productName\doc\

...\systems\
...\systems\systemName\
...\systems\systemName\doc\
...\systems\systemName\res\
...\systems\systemName\build\
...\systems\systemName\test\

...\library\
...\library\libraryName\
...\library\libraryName\doc\
...\library\libraryName\build\
...\library\libraryName\test\

...\devops\

製品

製品ごとに1つのフォルダー。ソフトウェアがビジネスをサポートする方法を伝えるのに役立ちます。

理想的には、各「製品」は、どのsystemsを呼び出し、どのように構成するかを示す構成ファイルにすぎません。 docサブフォルダには、最上位のブリーフ\スペックやプロモーション資料などを含めることができます...

製品とシステムを分離することにより、再利用の可能性をビジネスの顧客側に伝え、製品ごとのサイロを分解します。 (これは、同じ問題に対する「製品ライン」アプローチとは対照的です)

システム

システムごとに1つのフォルダー。リポジトリのコンテンツの主要な機能と機会/価値を伝えるのに役立ちます。

  1. ビルドおよびデプロイメント環境を指定する「構成管理」ファイル。
  2. システムレベルのテスト構成(大量になる可能性があります)。
  3. トップレベルのロジックと機能;最も重い作業はライブラリ関数によって行われます。

ライブラリ

さまざまなシステムによって呼び出される再利用可能なコンポーネント。ほとんどの開発活動は、システムではなくライブラリの作成を中心に編成されているため、再利用は開発プロセスに「組み込まれ」ます。

devops

ビルド、継続的インテグレーション、その他の開発自動化機能。

結論

ソースツリーは、ドキュメントの重要な部分であり、独自のテクノロジーとのビジネスの関係のアプローチ、構造、心理学を形成します。

このアプローチのドライバーについては、この質問に対する私の回答でもう少し詳しく説明します。 https://softwareengineering.stackexchange.com/questions/43733/who-organizes-your-matlab-code/59637#59637

6
William Payne

私は規約について本当に知りませんが、私の主なプロジェクトはすべてSymfony Frameworkを使用して行われ、次のようなツリー構造に慣れています。

ルート/

  • アプリ
  • app_name
    • config(アプリ固有の設定ファイル)
    • lib(アプリ固有のphpファイル)
    • モジュール(機能のモジュール式配布)
      • module_name
        • テンプレート(html)
        • アクション(phpコード)
  • confing(プロジェクト構成ファイル)
  • lib(holeプロジェクトで使用できるPHPコード)
  • モデル(プロジェクト情報を表すクラス)
    • ベース
  • フォーム(フォームを処理するphpファイル、これはsymfonyなしで実現するのはかなり難しいかもしれません)
    • ベース(基本フォームクラス)
  • web
  • css
    • 画像
    • file.css
  • js
  • ログ(生成される可能性のあるログファイル)
  • データ(SQLパッチなどのデータ固有の情報)
  • sQL
  • プラグイン(プロジェクトの任意のアプリとマージできる使用ライブラリ)

興味がある場合は、symfonyのドキュメントを読んで、さらにお問い合わせください( SymfonyのMVCおよびコード編成 )。

5
guiman

各プロジェクトで私がやろうとしていることは、次のようになります。

  • src-ソースファイル、ファイルを簡単に取得するための各名前空間/パッケージのフォルダー(C/C++のヘッダーファイルも)
  • ext-外部/サードパーティライブラリの場合、外部(SVNリポジトリなど)を追加するのは簡単です。内部には、各ライブラリーのフォルダー(バイナリーとインクルードファイル)
  • bin-ビルドされたバイナリの場合、リリース用にすばやくエクスポートできます
    • inc-C/C++ヘッダーファイル用(IDE/makefile/etc ...でコピー)
  • out-すべての一時的に生成されたファイル(.class、.objなど...)の場合、無視される可能性があります(たとえば、SVNによって)
  • doc-通常はDoxygenで生成されたドキュメント用
  • res-ここにリソースを配置することで、プログラムで使用されるテキストソースファイルとバイナリリソースを分離できます。内部には特定の階層はありません。
    • config-一部の構成ファイル
    • 描画可能-一部の画像またはアイコン用

IDEのすべてのファイルまたはメイクファイルは、そのうちの1つのみを使用する場合、ルートに直接保存されます。

3
Ninfomane

私はこのようなことをします。暇なときにやっているクロスプラットフォームのゲームに適しています。残念ながら仕事では、物事はあまり整理されていません...

Output                      <-- Build outputs
Docs
External
   <libname>
      Include
      Lib
Data
<ProjectName>.xcodeproj
<ProjectName>VS2010
Source
Temp                        <-- Intermediate stuff from builds and other tools
Tools
2
Colonel Panic

このページに掲載されているアイデアが気に入っています www.javapractices.com/topic/TopicAction.do?Id=205 。基本的には、プロジェクトを機能(またはモジュール、コンポーネント)に編成することをお勧めします。そこで提示された理由に加えて:

  1. 作業中の機能のコードはすべて「機能プライベート」であることが保証されているため、作業中のコードのスコープについて考えるときの認識の負荷が少なくなります。
  2. 特定の機能のコードのみを変更することが保証されている場合は、安心感が増します。たとえば、作業中の機能以外は何も壊しません。これも「機能プライベート」のためです。
  3. 特定のパッケージで表示できるファイルが少ないため、単純な認識ロード。誰もが15個を超えるファイルを含むパッケージを見たことがあると思います。

これはJavaパッケージ(別名名前空間)に焦点を合わせていることに注意してください。大きなプロジェクトの場合、同じ理由で、プロジェクトを(複数のmavenプロジェクトのように)複数のプロジェクトに分割して、ビジネス機能。mavenプロジェクトの場合、これをお勧めします reading

これまでのところ、私が関わっているプロジェクトは、これらに準拠していません。理由はたくさんありますが、いくつかあります:

  1. Javaデフォルトのアクセス修飾子の誤解(これは、ほとんど誤解されているアクセス修飾子 ))
  2. 「Argumentum ad populum」:レイヤーバイパッケージの一般的な文化(おそらく理由#1が原因)

建築家のアレクサンダーが言ったように、プロジェクトの開始時にプロジェクトのソース組織が真剣に受け取られない場合、複雑さを回避する機会を逃していると思います。

「デザイナーが言うように、それはデザインプロセスの最初のステップであり、ほとんどが重要です。フォームを作成する最初のいくつかのストロークは、残りの運命をその中に持ち込みます。」 -クリストファー・アレクサンダー

プロジェクトの規模と複雑さによっては、コストやROIを削減する機会を逃してしまうことは非常に大きなものになる可能性があります。 (これの正確な数値を確認するための調査に興味があります)

2
thirdy

私のチームでは、プロジェクト全体に標準的な構造を適用して、チームがコンテキストを切り替えるときに簡単に見つけられるようにし、毎回再学習する必要がないようにしています。すべてのプロジェクトがすべてのシステムを必要とするわけではないため、最小限のセットから始めます。

/ソース/コンポーネント/言語

/ Source/Component/3rd Party /

/ Documentation/Requirements

/ドキュメント/デザイン

/テスト/自動化/ユニット

/ Tests/Automated/ToolName

/テスト/手動

これにより、特にサードパーティのコードとライブラリの下で重複が発生しますが、少なくとも「RogueWaveエディターの使用方法」などに対する答えを忘れることはありません。

2

私の推奨は、さまざまなフレームワークまたはエンジンをダウンロードして、巨大な開発チームがどのようにフォルダーレイアウトを処理したかを確認することです。

ファイルを整理するには非常に多くの方法があるので、ファイルを選択し、任意のプロジェクトでそれを使用することをお勧めします。バグや不要な時間を失うことを回避するために、完成または改良するまで特定の規則に固執してください。

Webプロジェクト用のLaravel、Symphony、またはCodeigniterフレームワークをダウンロードして、機能するインスタントフォルダーレイアウトを作成できます。

そのため、どの開発にも共通するフォルダーレイアウトを伝えようとします。

MVC(Model View Controller)は、組織の優れたパラダイムを提供します。

ルートソースコードはsrc(C++)またはapp(Web開発)

グループ化されたクラスの明確な目的を持たないファイル構造は、間違いなく混乱を引き起こします。コードを整理するだけでなく、オートローダー、クラスファクトリ、ラップローカルストレージ、リモートストレージ、ネームスペースを維持できます。

このフォルダー構造はLaravel Frameworkから派生して簡略化されています。この投稿の好みは複数のネーミングですが、プロジェクトでは単数形の単語を使用しています。


src/storage(models/file-storage/api/mysql/sql-lite/memcached/redis implementations)

src/repositories(いくつかのストレージロジック、共通のインターフェース、および結果の返却規則を備えた「ストレージ実装」のラッパー。)

src/services | logic | entity(アプリビジネスロジック)

src/controllers(Web開発でサーバー要求をサービスにルーティングするために使用されます)

src/modules | systems(フレームワークの一般的な機能を拡張するモジュラーシステム。サービスはモジュールを使用できますが、その逆はできません)

src/helpers(文字列操作などのヘルパーまたはラッパークラス。多くの場合、これはlibs |ベンダーのサードパーティの場合)

src/types(名前付き列挙型)

public | build | output(webまたはc ++)

config(セットアップファイル。クロスプラットフォームの構成ファイルでYAMLが一般的になりつつあります)

キャッシュ

ログ

lang(en/es/ru/...)

bootstrap(フレームワークとアプリを起動します)

docs(マークダウン形式.mdで記述されたドキュメント)

tests(単体テスト)

database/migrations(データベース構造を最初から作成)

database/seeds(テストするダミーデータをデータベースに入力します)

libs | vendor(すべてのサードパーティソフトウェア。C++では「libs」、通常はphpでは「vendor」)

アセット|リソース(images/sounds/scripts/json/any media)

2
Heroselohim

オブジェクト指向言語を使用すると、名前空間を構築できます。結合を回避するためにアプリケーションの部分を分離するために使用されるその論理的な内訳は、論理ファイルの場所の内訳の主な原因です。名前空間を分解する理由としてカップリングを使用することは、開始するのに良い場所です http://en.wikipedia.org/wiki/Software_package_metrics

他の人はビルドに関連してプロジェクトを設定することについて話していますが、ソース自体にアクセスしたら、それは理にかなっていることです-とにかく論理的にコードを分解する方法を使用してください。

1
Travis