Bagaimana saya harus mengatur pohon sumber saya?


89

Saya seorang pengembang individu yang bekerja, sebagian besar, pada proyek web (W / LAMP) dan, kadang-kadang, pada proyek C / C ++ (non-GUI) dengan skala rata-rata.

Saya sering berjuang dengan struktur pohon kode sumber saya. Bahkan, biasanya, saya tidak menyelesaikan proyek tanpa membuang seluruh pohon dan menata ulang potongan tiga-empat kali yang benar-benar membutuhkan banyak usaha dan terlebih lagi hasil akhirnya tampak seperti kompromi.

Kadang-kadang, saya berakhir dengan lebih dari klasifikasi sumber - pohon folder dan sub-folder yang sangat panjang. Di lain waktu, saya hanya berkonsentrasi semua file dalam folder tertentu berdasarkan tujuan yang lebih besar yang mereka layani dan dengan demikian mengarah ke folder 'kacau' di sumbernya.

Saya ingin bertanya:

  • Apakah ada prinsip / logika / praktik terbaik yang dapat membantu saya lebih baik dalam struktur pohon sumber saya?
  • Adakah teknik grafis / diagram (misalnya: DFD dalam hal aliran data) yang dapat membantu saya memvisualisasikan struktur kode sumber saya sebelumnya berdasarkan analisis proyek?
  • Apa strategi untuk mengadopsi struktur multi-media file-pohon yang terkait dengan proyek?

Tentang hadiah : Saya menghargai jawaban yang ada dengan anggota yang berbagi praktik mereka sendiri, namun, saya ingin mendorong jawaban yang lebih umum dan instruktif (atau sumber daya) dan lebih banyak tanggapan dari anggota.


8
Saya tidak punya waktu untuk esai sekarang, tetapi "beri nama benda apa adanya", "letakkan barang-barang di tempat mereka", "simpan barang-barang serupa di dekat satu sama lain", dan akhirnya, "jangan khawatir tentang itu." , semoga Anda memiliki IDE yang akan membantu Anda dengan cepat menavigasi antar potongan kode ".
John Saunders

@ John, saya tidak begitu baik dengan IDE, saya biasanya mengeluarkan Notepad ++ atau vi tergantung pada OS. Itu membuat segalanya sedikit lebih sulit. Poin-poin lainnya sangat membantu tetapi sekali lagi hal itu bermuara pada pembuatan keputusan yang rumit seperti fungsi log (error logs dll) lebih dekat dengan logika aplikasi atau DAL atau manajemen cache atau manajer tampilan. Kesalahan memiliki kemungkinan yang hampir sama untuk terjadi di salah satu dari mereka.
check123

3
Mungkin begitu Anda sampai pada titik memiliki pertanyaan semacam ini, saatnya membiarkan beberapa alat melakukan beberapa pekerjaan untuk Anda. Dan logging jelas merupakan masalah lintas fungsional, yang digunakan oleh semua bagian aplikasi (jika Anda menggunakan jenis kode yang perlu logging). Pepatah kecil lainnya adalah, "letakkan kode di atas kode yang menggunakannya", jadi logging harus berada di dekat bagian atas, mungkin di \ utilities.
John Saunders

@ John: Sangat dihargai. Mungkin saya harus mulai mencari IDE. Gerhana tampaknya menjanjikan.
check123

1
@ check123 "... mengatur ulang potongan tiga-empat kali ..." Praktek umum: "Oleh karena itu, pertanyaan manajemen bukanlah apakah membangun sistem pilot dan membuangnya. Anda akan melakukannya. Satu-satunya pertanyaan adalah apakah akan merencanakan terlebih dahulu untuk membangun sebuah tempat pembuangan, atau berjanji untuk mengirimkan barang-barang tersebut kepada pelanggan. "- Frederick P. Brooks Jr., The Mythical Man-Month: Esai tentang Rekayasa Perangkat Lunak
shawnhcorey

Jawaban:


25

Tata letak pohon sumber harus mencerminkan arsitektur; sebagai akibat wajar, arsitektur yang terstruktur dengan baik dapat mengarah pada tata letak pohon sumber yang terstruktur dengan baik. Saya sarankan membaca pada pola Layers POSA1 , mencoba menyesuaikan arsitektur Anda ke dalam struktur berlapis, kemudian memberi nama setiap lapisan yang dihasilkan, dan menggunakannya sebagai dasar untuk hierarki sumber Anda. Mengambil arsitektur tiga tingkat sebagai dasar:

  • presentasi / layanan web (menyajikan antarmuka layanan web untuk logika bisnis kami)
  • logic / * (modul business logic masuk ke sini)
  • storage / sql (API penyimpanan back-end di sini - ini menggunakan antarmuka SQL untuk menyimpan ke database)
  • util / * (kode utilitas - dapat digunakan oleh semua lapisan lain, tetapi itu tidak merujuk util di luar, lihat di sini)

Perhatikan bahwa layer tidak mengandung kode secara langsung, tetapi lebih tepatnya digunakan untuk mengatur modul.

Dalam sebuah modul, saya menggunakan jenis tata letak berikut:

  • <module> (jalur ke modul secara langsung; mendefinisikan antarmuka modular)
  • <module>/impl/<implName> (implementasi spesifik dari antarmuka modular)
  • <module>/doc (Dokumentasi untuk menggunakan modul)
  • <module>/tb (kode unit-test untuk modul)

di mana <module>terletak di repositori sesuai dengan lapisan tempatnya.


5
+1: Tata letak pohon sumber harus mencerminkan arsitektur - hal yang jelas saya abaikan.
check123

Bagaimana Anda mengelola file aman - file yang hanya dapat diakses oleh pengguna yang berwenang setelah login?
check123

@ check123 Saya tidak yakin saya mengerti pertanyaannya. Saya fokus pada organisasi modul sumber, daripada mendukung file untuk proyek, dan kode sumber biasanya dimaksudkan untuk dapat diakses oleh semua orang. (Ada pengecualian, dan saya menggunakan dist / direktori di atas semua kode dengan pembatasan penggunaan / modifikasi non-standar.)
Aidan Cully

48

Saya benar-benar tidak bisa memberi Anda banyak saran yang berkaitan dengan proyek web, tetapi inilah cara saya menyusun struktur pohon saya dalam proyek pemrograman (terutama dari perspektif C / C ++):

  • /
    • src - Sumber file yang ditulis oleh saya sendiri
    • ext - Berisi perpustakaan pihak ketiga
      • libname-1.2.8
        • termasuk - Tajuk
        • lib - File lib yang dikompilasi
        • Donwload.txt - Berisi tautan untuk mengunduh versi yang digunakan
    • ide - Saya menyimpan file proyek di sini
      • vc10 - Saya mengatur file proyek tergantung pada IDE
    • bin - Exe yang dikompilasi ada di sini
    • build - File build kompiler
    • doc - Dokumentasi apa pun
    • Baca aku
    • PASANG
    • PENYALINAN

Beberapa catatan:

  1. Jika saya sedang menulis perpustakaan (dan saya menggunakan C / C ++) saya akan mengatur file sumber saya terlebih dahulu dalam dua folder yang disebut "include" dan "src" dan kemudian dengan modul. Jika ini adalah aplikasi, maka saya akan mengaturnya hanya dengan modul (header dan sumber akan masuk ke folder yang sama).

  2. File dan direktori yang saya cantumkan di atas dalam huruf miring, saya tidak akan menambahkan ke repositori kode.


Apa perbedaan antara ide dan membangun ?
M. Dudley

3
idehanya tempat saya menyimpan file proyek sendiri. buildberisi file objek yang dihasilkan oleh kompiler. IDE yang berbeda dapat menggunakan kompiler yang sama, jadi itu sebabnya saya menjaga file proyek IDE terpisah dari file objek yang dibangun oleh kompiler.
Paul

jadi build == obj (istilah yang digunakan oleh banyak sistem lain)
gbjbaanb

@ gbjbaanb Ya, saya kira. Tidak masalah karena direktori itu tidak didorong ke repositori. :) Saya menyebutnya 'build' karena itulah IDE yang saya gunakan att menyebutnya (Visual Studio).
Paul

Bagaimana jika exe Anda perlu dll untuk menjalankan? Apakah Anda menyalin semua file dll ke dir yang sama dengan exe? Apakah Anda menggunakan beberapa peristiwa post-build?
Wakan Tanka

14

Sementara Layout Direktori Standar Maven jenis khusus untuk Java, tetapi mungkin berfungsi sebagai dasar yang baik untuk jenis proyek lainnya juga.

Berikut adalah struktur dasarnya (Anda bisa mengganti direktori 'java' dengan 'php', 'cpp', dll):

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

Struktur pada dasarnya terurai menjadi 'src / main' dan 'src / test' kemudian dikelompokkan berdasarkan jenis.


5

Saya tidak benar-benar tahu tentang konvensi tetapi semua proyek utama saya selesai menggunakan Symfony Framework dan saya telah terbiasa dengan struktur pohon seperti berikut:

akar/

  • aplikasi
  • nama aplikasi
    • config (file konfigurasi khusus aplikasi)
    • lib (file php khusus aplikasi)
    • modul (distribusi fungsionalitas modular)
      • module_name
        • templat (html)
        • tindakan (kode php)
  • confing (proyek file konfigurasi)
  • lib (kode php yang dapat digunakan dalam proyek lubang)
  • model (kelas yang mewakili informasi proyek)
    • mendasarkan
  • form (file php yang menangani form, ini bisa sangat sulit dicapai tanpa symfony)
    • base (kelas bentuk dasar)
  • web
  • css
    • gambar-gambar
    • file.css
  • js
  • log (file log yang mungkin dihasilkan)
  • data (informasi spesifik data, seperti tambalan sql, atau apa pun)
  • sql
  • plugins (perpustakaan yang digunakan yang dapat digabungkan dengan aplikasi proyek apa pun)

Jika Anda tertarik, silakan baca dokumentasi symfony tentang masalah ini untuk ditanyakan lebih lanjut ( MVC dan Code Organisation on Symfony ).


Apakah folder CSS Anda terpusat? Maksud saya semua CSS Anda (lintas proyek) berada di direktori yang sama?
check123

Tidak harus, Anda dapat membaginya, tetapi karena sebagian besar proyek saya cenderung hanya memiliki 2 aplikasi (frontend dan backend), tidak ada banyak file css (plugin selalu memiliki folder web sendiri untuk abstraksi)
guiman

5

Idealnya, organisasi memiliki repositori tunggal, struktur yang dimaksudkan untuk meningkatkan keterlibatan antara teknik & bisnis dan mempromosikan penggunaan kembali.

...\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\

produk

Satu folder per produk; membantu mengomunikasikan bagaimana perangkat lunak mendukung bisnis.

Idealnya, setiap "produk" tidak lebih dari file konfigurasi yang menunjukkan sistem mana yang harus dipanggil dan bagaimana mereka harus dikonfigurasi. Subfolder dokumen dapat berisi brief \ spec \ tingkat atas & materi promosi apa pun dll ...

Dengan memisahkan produk dan sistem, kami mengomunikasikan potensi penggunaan kembali ke sisi bisnis yang dihadapi pelanggan, dan memecah silo per produk. (Ini kontras dengan pendekatan "lini produk" untuk masalah yang sama)

sistem

Satu folder per sistem; membantu mengomunikasikan kemampuan & peluang / nilai utama dari isi repositori.

  1. File "Manajemen konfigurasi" yang menetapkan lingkungan pengembangan & penyebaran.
  2. Konfigurasi pengujian tingkat sistem (bisa berupa jumlah yang signifikan).
  3. Logika & fungsionalitas tingkat atas; sebagian besar pengangkatan berat dilakukan oleh fungsi perpustakaan.

Perpustakaan

Komponen yang dapat digunakan kembali dipicu oleh berbagai sistem. Sebagian besar kegiatan pengembangan diselenggarakan di sekitar produksi perpustakaan, bukan sistem, sehingga penggunaan kembali "dimasukkan ke dalam" proses pengembangan.

devops

Membangun, Integrasi Berkelanjutan & fungsi Otomasi Pengembangan lainnya.

Kesimpulan

Source tree adalah bagian penting dari dokumentasi, dan membentuk pendekatan, struktur dan psikologi hubungan bisnis dengan teknologi yang dimilikinya.

Driver untuk pendekatan ini dijelaskan sedikit lebih dalam dalam jawaban saya untuk pertanyaan ini: https://softwareengineering.stackexchange.com/questions/43733/who-organizes-your-matlab-code/59637#59637


Catatan: Mungkin berguna untuk memberi nama folder dengan cara yang kompatibel dengan jenis hierarki produk yang dibahas dalam buku pegangan teknik sistem INCOSE.
William Payne

3

Apa yang saya coba lakukan untuk setiap proyek serupa dengan:

  • src - file sumber, folder untuk setiap namespace / paket untuk dengan mudah mengambil file (bahkan file header untuk C / C ++)
  • ext - untuk perpustakaan eksternal / pihak ketiga, mudah untuk menambahkan eksternal (seperti repositori SVN). Di dalam, folder untuk setiap perpustakaan (binari dan sertakan file)
  • bin - untuk binari binaan, dapat dengan cepat diekspor untuk dirilis
    • inc - untuk file header C / C ++ (disalin oleh IDE / makefile / etc ...)
  • keluar - untuk semua file yang dibuat sementara (.class, .obj dll ...) dan itu dapat diabaikan (misalnya oleh SVN)
  • doc - untuk dokumentasi apa pun, biasanya dibuat dengan Doxygen
  • res - dengan menempatkan sumber daya di sini, dimungkinkan untuk memisahkan file sumber teks dan sumber daya biner yang digunakan oleh program. Saya tidak benar-benar memiliki hierarki spesifik di dalamnya.
    • config - untuk beberapa file konfigurasi
    • dapat ditarik - untuk beberapa gambar atau ikon

Semua file IDE atau makefile disimpan langsung di root jika Anda hanya menggunakan salah satunya.


2

Saya melakukan sesuatu seperti ini. Bekerja dengan baik untuk permainan lintas platform yang saya lakukan di waktu luang saya. Sayangnya dalam pekerjaan, banyak hal yang kurang terorganisir ...

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

2

Untuk tim saya, kami mencoba untuk menegakkan struktur standar di seluruh proyek agar mudah untuk menemukan hal-hal sebagai tim mengubah konteks dan untuk menghindari keharusan mempelajari kembali setiap kali melalui. Tidak semua proyek membutuhkan semua sistem jadi kami mulai dengan set minimal.

/ Sumber / Komponen / Bahasa

/ Sumber / Komponen / Pihak Ketiga /

/Persyaratan dokumen

/ Dokumentasi / Desain

/ Tes / Otomatis / Unit

/ Tes / Otomatis / Nama Alat

/ Tes / Manual

Ini menghasilkan duplikasi, khususnya di bawah kode Pihak Ketiga dan perpustakaan, tetapi setidaknya kita tidak pernah lupa jawaban untuk sesuatu seperti "Apa yang menggunakan Editor RogueWave?"


1
Komponen jalur bermodal terlihat sangat konyol dan tidak berguna bagi saya. Kenapa banyak sekali huruf kecil? Itu jauh lebih mudah untuk diketik untuk manusia (sementara alat tidak peduli, termasuk manajer file WIMP ), dan membaca dengan baik berkat pemisah jalur. Kemenangan yang pasti bagi saya.
ulidtko

2

Saya menyukai gagasan yang disajikan di halaman ini www.javapractices.com/topic/TopicAction.do?Id=205 . Pada dasarnya, rekomendasinya adalah mengatur proyek Anda menjadi fitur (atau modul, komponen). Selain alasan yang disajikan di sana:

  1. Mengurangi muatan kognitif saat Anda memikirkan tentang cakupan kode yang sedang Anda kerjakan karena Anda memiliki jaminan bahwa kode apa pun dalam fitur yang sedang Anda kerjakan adalah "fitur-pribadi".
  2. Ada rasa aman tambahan ketika Anda dijamin hanya mengubah kode untuk fitur yang diberikan. Misalnya, Anda tidak akan merusak apa pun selain fitur yang sedang Anda kerjakan. Sekali lagi ini karena "fitur-pribadi".
  3. Kurang memuat kognitif sederhana karena ada lebih sedikit file yang dapat Anda lihat untuk paket yang diberikan. Saya yakin semua orang telah melihat paket yang berisi lebih dari 15 file.

Catatan ini difokuskan pada paket Java (alias ruang nama). Untuk proyek besar, saya merekomendasikan, untuk alasan yang sama, membagi proyek menjadi beberapa proyek (seperti dalam beberapa proyek pakar) yang mewakili fitur bisnis. Untuk proyek pakar, saya merekomendasikan bacaan ini .

Sejauh ini, proyek yang saya / saya ikuti tidak mengikuti ini. Ada banyak alasan, tetapi inilah beberapa:

  1. Kesalahpahaman pengubah akses default Java (pengubah akses yang paling salah dipahami sesuai buku ini )
  2. "Argumentum ad populum": Kultur paket-by-layer yang berlaku (mungkin disebabkan oleh Alasan # 1)

Saya pikir ada peluang yang terlewatkan untuk mencegah kompleksitas jika organisasi sumber proyek tidak ditanggapi dengan serius pada awal proyek seperti yang dikatakan arsitek Alexander:

"Seperti yang akan dikatakan oleh desainer mana pun, itu adalah langkah pertama dalam proses desain yang paling penting. Beberapa goresan pertama, yang menciptakan bentuk, membawa di dalamnya takdir sisanya." - Christopher Alexander

Bergantung pada ukuran & kompleksitas proyek, peluang yang terlewatkan untuk memangkas biaya atau ROI bisa sangat besar. (Saya tertarik melihat studi untuk melihat angka pasti untuk ini)


2

Rekomendasi saya adalah mengunduh berbagai kerangka kerja atau mesin dan melihat bagaimana tim pengembang menangani tata letak folder mereka.

Ada begitu banyak cara untuk mengatur file sehingga lebih baik untuk memilih satu, dan mencoba untuk tetap menggunakannya pada proyek tertentu. Tetap pada konvensi tertentu sampai selesai atau pembenahan untuk menghindari bug dan kehilangan waktu yang tidak perlu.

Anda dapat mengunduh kerangka kerja Laravel, Symphony atau Codeigniter untuk proyek web agar memiliki tata letak folder instan yang berfungsi.

Jadi saya akan mencoba menyampaikan tata letak folder yang umum untuk pengembangan apa pun:

MVC (Model View Controller) memberikan paradigma organisasi yang baik.

Kode sumber root bisa berupa src (C ++) atau aplikasi (pengembangan web)

Struktur file yang tidak memiliki tujuan yang jelas untuk kelas yang dikelompokkannya pasti akan menyebabkan kebingungan. Ini tidak hanya untuk mengatur kode, tetapi juga dapat mempertahankan auto-loaders, pabrik kelas, bungkus penyimpanan lokal, penyimpanan jarak jauh dan penempatan nama.

Struktur folder ini diturunkan dan disederhanakan dari Laravel Framework . Preferensi saya pada posting ini adalah penamaan jamak tetapi saya menggunakan kata-kata tunggal dalam proyek saya.


src / storage (model / file-storage / api / mysql / sql-lite / memcached / redis implementasi)

src / repositori (Pembungkus 'implementasi penyimpanan' dengan beberapa logika penyimpanan, antarmuka umum dan kembalinya konvensi hasil.)

src / layanan | logika | entitas (Logika bisnis aplikasi)

src / controllers (Digunakan pada pengembangan web untuk merutekan permintaan server ke layanan Anda)

src / modules | sistem ( Sistem modular yang memperluas fungsionalitas umum kerangka kerja Anda. Layanan dapat menggunakan modul tetapi tidak sebaliknya)

src / helpers (Kelas pembantu atau pembungkus seperti mis. manipulasi string. Sering kali ini bisa berada di libs | vendor saat pihak ketiga)

src / types (Dinamai enum)

publik | membangun | output (web atau c ++)

config (Setup file. YAML menjadi populer untuk file konfigurasi lintas-platform)

cache

log

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

bootstrap (Mulai kerangka kerja dan aplikasi)

docs (Dokumentasi ditulis dalam format markdown .md)

tes (pengujian Unit)

database / migrasi (Buat struktur database dari awal)

database / seed (Mengisi database Anda dengan data dummy untuk diuji)

libs | vendor (semua perangkat lunak pihak ketiga. 'libs' di C ++ dan 'vendor' biasanya di php)

aset | sumber daya (gambar / suara / skrip / json / media apa saja)


1

Dengan bahasa yang berorientasi objek, Anda memiliki kemampuan untuk membangun ruang nama. Kerusakan logis yang digunakan untuk memisahkan bagian-bagian aplikasi untuk menghindari penggandengan adalah sumber utama kerusakan lokasi file logis. Menggunakan kopling sebagai alasan untuk memecah ruang nama adalah tempat yang baik untuk memulai http://en.wikipedia.org/wiki/Software_package_metrics .

Orang lain telah berbicara tentang menyiapkan proyek dalam kaitannya dengan membangun, tetapi begitu Anda masuk ke sumber itu sendiri, ini tentang apa yang masuk akal - cukup gunakan bagaimana Anda secara logis memecah kode.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.