ฉันมีโปรเจ็กต์ go ที่เริ่มซับซ้อนมากขึ้นและต้องการจัดวางระบบไฟล์เพื่อลดความเจ็บปวด
มีตัวอย่างที่ดีในสิ่งที่สมเหตุสมผลหรือไม่?
ฉันมีโปรเจ็กต์ go ที่เริ่มซับซ้อนมากขึ้นและต้องการจัดวางระบบไฟล์เพื่อลดความเจ็บปวด
มีตัวอย่างที่ดีในสิ่งที่สมเหตุสมผลหรือไม่?
คำตอบ:
อัปเดตพฤษภาคม 2013: เอกสารอย่างเป็นทางการอยู่ในส่วน " Code organization "
รหัสไปจะต้องเก็บไว้ภายในพื้นที่ทำงาน
เวิร์กสเปซคือลำดับชั้นของไดเร็กทอรีที่มีไดเร็กทอรีสามไดเร็กทอรีที่รูท:
src
มีไฟล์ต้นฉบับของ Go ที่จัดเป็นแพ็คเกจ (หนึ่งแพ็คเกจต่อไดเรกทอรี)pkg
มีวัตถุแพคเกจและbin
มีคำสั่งปฏิบัติการ
go tool
สร้างแพคเกจติดตั้งแหล่งที่มาและไบนารีที่เกิดขึ้นไปpkg
และbin
ไดเรกทอรีโดย
src
ทั่วไปไดเร็กทอรีย่อยจะมีที่เก็บการควบคุมเวอร์ชันหลายรายการ (เช่นสำหรับ Git หรือ Mercurial) ที่ติดตามการพัฒนาแพ็กเกจต้นทางอย่างน้อยหนึ่งแพ็กเกจ
bin/
streak # command executable
todo # command executable
pkg/
linux_amd64/
code.google.com/p/goauth2/
oauth.a # package object
github.com/nf/todo/
task.a # package object
src/
code.google.com/p/goauth2/
.hg/ # mercurial repository metadata
oauth/
oauth.go # package source
oauth_test.go # test source
อัปเดตกรกฎาคม 2014: ดู "การจัดโครงสร้างแอปพลิเคชันใน Go " จากBen Johnson
บทความนั้นมีเคล็ดลับเช่น:
การรวม
main.go
ไฟล์และตรรกะแอปพลิเคชันของฉันในแพ็คเกจเดียวกันมีผลสองประการ:
- ทำให้แอปพลิเคชันของฉันใช้งานไม่ได้ในฐานะห้องสมุด
- ฉันสามารถมีไบนารีแอปพลิเคชันเดียวเท่านั้น
วิธีที่ดีที่สุดที่ฉันพบในการแก้ไขปัญหานี้คือเพียงแค่ใช้
cmd
ไดเร็กทอรี“” ในโปรเจ็กต์ของฉันโดยที่ไดเร็กทอรีย่อยแต่ละไดเร็กทอรีเป็นไบนารีของแอปพลิเคชัน
camlistore/
cmd/
camget/
main.go
cammount/
main.go
camput/
main.go
camtool/
main.go
การย้าย
main.go
ไฟล์ออกจากรูทช่วยให้คุณสร้างแอปพลิเคชันของคุณจากมุมมองของไลบรารี ไบนารีแอปพลิเคชันของคุณเป็นเพียงไคลเอนต์ของไลบรารีแอปพลิเคชันของคุณบางครั้งคุณอาจต้องการให้ผู้ใช้โต้ตอบได้หลายวิธีดังนั้นคุณจึงต้องสร้างไบนารีหลายรายการ
ตัวอย่างเช่นหากคุณมีadder
แพ็กเกจ“” ที่ให้ผู้ใช้เพิ่มหมายเลขเข้าด้วยกันคุณอาจต้องการปล่อยเวอร์ชันบรรทัดคำสั่งและเวอร์ชันสำหรับเว็บ
คุณสามารถทำได้อย่างง่ายดายโดยจัดโครงการของคุณดังนี้:
adder/
adder.go
cmd/
adder/
main.go
adder-server/
main.go
ผู้ใช้สามารถติดตั้งไบนารีแอปพลิเคชัน“ adder” ด้วย“ go get” โดยใช้จุดไข่ปลา:
$ go get github.com/benbjohnson/adder/...
และ voila ผู้ใช้ของคุณได้ติดตั้ง“
adder
” และ“adder-server
” ไว้แล้ว!
โดยปกติประเภทของโครงการของฉันจะเกี่ยวข้องกันมากดังนั้นจึงเหมาะกับการใช้งานและมุมมองของ API มากกว่า
ประเภทเหล่านี้ยังสามารถใช้ประโยชน์จากการโทรที่ไม่ได้ส่งออกระหว่างพวกเขาซึ่งทำให้ API มีขนาดเล็กและชัดเจน
- จัดกลุ่มประเภทและรหัสที่เกี่ยวข้องเข้าด้วยกันในแต่ละไฟล์ หากประเภทและฟังก์ชันของคุณได้รับการจัดระเบียบอย่างดีฉันพบว่าไฟล์มักจะอยู่ระหว่าง 200 ถึง 500 SLOC อาจฟังดูเหมือนมาก แต่ฉันคิดว่ามันง่าย 1,000 SLOC มักจะเป็นขีด จำกัด สูงสุดของฉันสำหรับไฟล์เดียว
- จัดระเบียบประเภทที่สำคัญที่สุดที่ด้านบนของไฟล์และเพิ่มประเภทที่ลดความสำคัญลงที่ด้านล่างของไฟล์
- เมื่อแอปพลิเคชันของคุณเริ่มได้รับ SLOC มากกว่า 10,000 รายการคุณควรประเมินอย่างจริงจังว่าสามารถแบ่งออกเป็นโครงการขนาดเล็กได้หรือไม่
หมายเหตุ: การปฏิบัติครั้งสุดท้ายไม่ดีเสมอไป:
ขออภัยฉันไม่เห็นด้วยกับแนวทางปฏิบัตินี้
การแยกประเภทเป็นไฟล์ช่วยในการจัดการโค้ดความสามารถในการอ่านการบำรุงรักษาการทดสอบ
นอกจากนี้ยังอาจรับประกันความรับผิดชอบเดียวและปฏิบัติตามหลักการเปิด / ปิด ...
กฎสำหรับการไม่อนุญาตให้มีการพึ่งพาแบบวงกลมคือการบังคับให้เรามีโครงสร้างที่ชัดเจนของบรรจุภัณฑ์
(ทางเลือกในเดือนกุมภาพันธ์ 2013 src
เท่านั้น)
คุณสามารถดูเค้าโครงคลาสสิกที่แสดงใน " เค้าโครงโค้ด GitHub ":
แอปและไลบรารีทั้งสองอยู่บน Github แต่ละแห่งอยู่ในที่เก็บของตัวเอง
$GOPATH
เป็นรากของโครงการ - แต่ละ Repos Github ของคุณจะถูกตรวจสอบจากหลาย ๆ$GOPATH
โฟลเดอร์ด้านล่างเลย์เอาต์โค้ดของคุณจะมีลักษณะดังนี้:
$GOPATH/
src/
github.com/
jmcvetta/
useless/
.git/
useless.go
useless_test.go
README.md
uselessd/
.git/
uselessd.go
uselessd_test.go
README.md
แต่ละโฟลเดอร์ที่อยู่ด้านล่าง
src/github.com/jmcvetta/
คือรูทของการชำระเงินคอมไพล์แยกกัน
สิ่งนี้ดึงดูดการวิพากษ์วิจารณ์บางอย่างในหน้า reddit นี้ :
ฉันขอแนะนำอย่างยิ่งว่าอย่าจัดโครงสร้าง repo แบบที่คุณมีมันจะพัง "
go get
" ซึ่งเป็นหนึ่งในสิ่งที่มีประโยชน์ที่สุดเกี่ยวกับ Go
การเขียนโค้ดของคุณสำหรับคนที่รู้จัก Go นั้นดีกว่ามากเนื่องจากพวกเขามักจะเป็นคนที่รวบรวมมัน
และสำหรับคนที่ไม่มีอย่างน้อยพวกเขาก็จะรู้สึกถึงภาษาใส่แพ็กเกจหลักในรูทของ repo
มีเนื้อหาในไดเรกทอรีย่อย (เพื่อให้ทุกอย่างเรียบร้อย)
เก็บเนื้อของรหัสไว้ในแพ็กเกจย่อย (ในกรณีที่ใครก็ตามต้องการใช้ซ้ำนอกไบนารีของคุณ)
รวมสคริปต์การตั้งค่าไว้ในรูทของ repo เพื่อให้ค้นหาได้ง่ายยังคงเป็นเพียงขั้นตอนสองขั้นตอนในการดาวน์โหลดสร้างติดตั้งและตั้งค่า:
- "
go get <your repo path>
": ดาวน์โหลดและติดตั้งโค้ด go พร้อม subdir สำหรับเนื้อหา$GOPATH/<your repo path>/setup.sh
: กระจายทรัพย์สินไปยังสถานที่ที่เหมาะสมและติดตั้งบริการ
ฉันคิดว่าใน 'โครงการ' คุณไม่ได้หมายถึงแพ็คเกจ Go แต่เป็นซอฟต์แวร์ที่คุณพัฒนา มิฉะนั้นคุณจะได้รับความช่วยเหลือที่นี่และที่นี่ อย่างไรก็ตามการเขียนแพ็คเกจสำหรับ Go ไม่แตกต่างกันมากนัก: ใช้แพ็คเกจสร้างโฟลเดอร์สำหรับแต่ละแพ็คเกจและรวมแพ็คเกจเหล่านั้นในแอปพลิเคชันของคุณ
เพื่อสร้างตัวเองความเห็นคุณสามารถดูแนวโน้มที่เก็บไปบน GitHub: https://github.com/trending/go ตัวอย่างที่โดดเด่น ได้แก่เคย์ลีย์ และซีอุส
รูปแบบที่ได้รับความนิยมมากที่สุดอาจจะมีไฟล์ Go หลักและโมดูลและโมดูลย่อยจำนวนมากในไดเร็กทอรีของตนเอง ในกรณีที่คุณมีไฟล์เมตาจำนวนมาก (doc, license, template, ... ) คุณอาจต้องการใส่ซอร์สโค้ดลงในไดเร็กทอรีย่อย นั่นคือสิ่งที่ฉันทำจนถึงตอนนี้
$GOPATH/src
หรือใช้ของพวกเขาgo get
ชื่อโต๊ะ
doozerd
ไม่ใช่ตัวอย่างที่ดีแม้การทดสอบจะอ่อนแอ
มีแนวทางที่แนะนำจากผู้เขียนของ Golang ซึ่งกำหนดวิธีการจัดวางโค้ดของคุณเพื่อให้ทำงานได้ดีที่สุดกับเครื่องมือ go และเพื่อสนับสนุนระบบควบคุมแหล่งที่มา
$GOROOT
ไม่ใช่รหัสภายในsrc/<project>
ไดเรกทอรี
คุณควรดูที่ repo นี้ด้วย แสดงแนวคิดมากมายในการจัดโครงสร้างแอปพลิเคชันไป: https://github.com/golang-standards/project-layout
setup.sh
คือ Go เป็นข้ามแพลตฟอร์มที่สมเหตุสมผลในขณะที่เชลล์สคริปต์ POSIX ไม่ใช่