ソースツリーを整理する方法


89

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

私はしばしばソースコードツリーの構築に苦労しています。実際、通常、ツリー全体をダンプして3〜4回再配置することなくプロジェクトを完了することはありません。

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

私は尋ねたい:

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

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


8
今はエッセイの時間はありませんが、「物事に名前を付ける」、「物事が属する場所に物事を置く」、「似たような物事をお互いに近づける」、最後に「心配しないで」 、できればコード間をすばやく移動するのに役立つIDEがあればいいのです」。
ジョンサンダース

@ジョン、私はIDEがあまり得意ではありません、私は一般的にOSに応じてNotepad ++またはviを引き出します。それは物事をもう少し難しくします。残りのポイントは役に立ちますが、やはり、ログ(エラーログなど)機能のようなトリッキーな決定をアプリケーションロジックまたはDALまたはキャッシュ管理またはビューマネージャーにより近づけることになります。エラーは、どのエラーでもほぼ同じ確率で発生します。
check123

3
たぶん、この種の質問ができるようになったら、いくつかのツールに作業を任せる時間になります。また、ロギングは明らかに機能を超えた関心事であり、アプリケーションのすべての部分で使用されます(ロギングが必要な種類のコードを使用している場合)。もう1つの小さな言い方は、「それを使用するコードの上にコードを配置する」ことです。そのため、ロギングは最上部近く、おそらく\ utilitiesにあるはずです。
ジョンサンダース

@ジョン:ありがたい。IDEを探し始めるべきかもしれません。Eclipseは有望なようです。
check123

1
@ check123 "...部品を3〜4回並べ替える..."一般的な慣行: "したがって、管理上の問題は、パイロットシステムを構築して廃棄するかどうかではありません。あなたはそれをするでしょう。唯一の問題は、使い捨てを構築するために、事前に計画する、または顧客への使い捨てをお届けすることを約束するかどうかである「 -フレデリック・P.ブルックスJr.の、人月の神話:ソフトウェア工学上のエッセイ
shawnhcorey

回答:


25

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

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

レイヤーにはコードが直接含まれておらず、モジュールを整理するために厳密に使用されていることに注意してください。

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

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

<module>属しているレイヤーに応じて、リポジトリ内のがどこにあるか。


5
+1:ソースツリーレイアウトはアーキテクチャを反映する必要があります-私が見落としていたことは明らかです。
check123

安全なファイル-承認されたユーザーのみがログイン後のアクセスにアクセスできるファイルを管理しますか?
check123

@ check123質問を理解したかどうかわかりません。プロジェクトのファイルをサポートするのではなく、ソースモジュールの編成に焦点を当てました。通常、ソースコードは誰でもアクセスできるようになっています。(例外があり、非標準の使用/変更の制限があるすべてのコードの上にdist /ディレクトリを使用しています。)
エイダンカリー

48

Webプロジェクトに関連するアドバイスはあまりできませんが、プログラミングプロジェクトでツリーを構成する方法は次のとおりです(主にC / C ++の観点から)。

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

いくつかのメモ:

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

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


idebuildの違いは何ですか?
M.ダドリー

3
ideプロジェクトファイル自体を保存する場所です。buildコンパイラによって生成されたオブジェクトファイルが含まれます。異なるIDEが同じコンパイラを使用する場合があるため、IDEプロジェクトファイルを、コンパイラによって構築されたオブジェクトファイルから分離したままにします。
ポール

ビルド== obj(他の多くのシステムで使用される用語)
gbjbaanb

@gbjbaanbうん、そうだね。そのディレクトリはリポジトリにプッシュされないため、実際には問題ではありません。:)私が「ビルド」と呼んだのは、私が使用していたIDEがそれを呼んだものだからです(Visual Studio)。
ポール

exeの実行にdllが必要な場合はどうなりますか?すべてのdllファイルをexeと同じディレクトリにコピーしますか?いくつかのビルド後イベントを使用しますか?
和漢短歌

14

一方で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」に分類され、タイプごとにグループ化されます。


5

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

ルート/

  • アプリ
  • app_name
    • config(アプリ固有の構成ファイル)
    • lib(アプリ固有のphpファイル)
    • モジュール(機能のモジュラー配布)
      • module_name
        • テンプレート(html)
        • アクション(PHPコード)
  • confing(プロジェクト構成ファイル)
  • lib(holeプロジェクトで使用できるPHPコード)
  • モデル(プロジェクト情報を表すクラス)
    • ベース
  • フォーム(フォームを処理するphpファイル。これはsymfonyなしで達成するのは非常に困難です)
    • ベース(ベースフォームクラス)
  • ウェブ
  • CSS
    • 画像
    • file.css
  • js
  • ログ(生成される可能性のあるログファイル)
  • データ(SQLパッチなどのデータ固有の情報など)
  • sql
  • プラグイン(プロジェクトの任意のアプリとマージできるライブラリを使用)

興味のある方は、symfonyのドキュメントを読んで、さらに問い合わせてください(MVCとCodes on Symfonyの組織)。


CSSフォルダーは集中化されていますか?すべてのCSS(プロジェクト全体)が同じディレクトリにあることを意味しますか?
check123

必ずしもそうではありません、あなたはそれを分割することもできますが、私のプロジェクトのほとんどは唯一の2のアプリケーション(フロントエンドとバックエンド)を有する傾向があるとして、そのくらいのCSSファイルは、(プラグインは常に抽象化のために自分のWebフォルダが)存在しません
guiman

5

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

...\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つのフォルダー。ソフトウェアがビジネスをサポートする方法を伝えるのに役立ちます。

理想的には、各「製品」は、起動するシステムとそれらの構成方法を示す構成ファイルにすぎません。docサブフォルダーには、トップレベルのbrief \ specおよびプロモーション資料などを含めることができます。

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

システム

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

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

図書館

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

devops

ビルド、継続的統合、およびその他の開発自動化機能。

結論

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

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


注:INCOSEシステムエンジニアリングハンドブックで説明されている製品階層の種類と互換性のある方法でフォルダに名前を付けると便利な場合があります。
ウィリアムペイン

3

各プロジェクトで私がやろうとしていることは次のようなものです:

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

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


2

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

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

2

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

/ Source / Component / Language

/ Source / Component / 3rd Party /

/ドキュメント/要件

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

/ Tests / Automated / Unit

/ Tests / Automated / ToolName

/テスト/マニュアル

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


1
大文字のパスコンポーネントは、本当にばかげて無意味に見えます。なぜすべて小文字なのか?これは人間にとっては非常に簡単に入力できますが(ツールはWIMPファイルマネージャーを含めて気にしません)、パス区切り文字のおかげで同様に読みやすくなります。私にとって決定的な勝利。
ウリトコ

2

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

  1. 作業中の機能のコードはすべて「機能プライベート」であることが保証されているため、作業中のコードの範囲を考えるときの認知的負荷が少なくなります。
  2. 特定の機能のコードを変更するだけであることが保証されている場合は、追加のセキュリティ感があります。たとえば、作業中の機能以外は何も壊しません。繰り返しますが、これは「機能プライベート」のためです。
  3. 特定のパッケージで表示できるファイルが少ないため、認知負荷が軽減されます。誰もが15個を超えるファイルを含むパッケージを見たことがあると思います。

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

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

  1. Javaのデフォルトのアクセス修飾子の誤解(この本によるとほとんどの誤解されたアクセス修飾子)
  2. 「Argument ad populum」:パッケージごとの一般的な文化(おそらく理由#1が原因)

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

「設計者なら誰でも言うように、それは設計プロセスの最初のステップであり、最も重要なことです。フォームを作成する最初の数ストロークは、その中に残りの運命を運びま​​す。」-クリストファー・アレクサンダー

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


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の実装)

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

src / services | ロジック| エンティティ (アプリビジネスロジック)

src / controllers(Web開発でサーバーリクエストをサービスにルーティングするために使用)

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

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

src / types(名前付き列挙)

公開| ビルド| 出力(webまたはc ++)

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

キャッシュ

ログ

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

ブートストラップ(フレームワークとアプリを起動します)

docs(マークダウン形式の.mdで書かれたドキュメント)

テスト(単体テスト)

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

データベース/シード(テストするダミーデータでデータベースを満たします)

ライブラリ| ベンダー(すべてのサードパーティソフトウェア。C++では「libs」、通常はPHPで「vendor」)

資産| リソース(画像/音声/スクリプト/ json /任意のメディア)


1

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.