Tôi có một dự án bắt đầu trở nên phức tạp hơn và muốn sắp xếp hệ thống tệp theo cách như vậy để giảm bớt sự cố.
Có một số ví dụ điển hình về những gì có ý nghĩa không?
Tôi có một dự án bắt đầu trở nên phức tạp hơn và muốn sắp xếp hệ thống tệp theo cách như vậy để giảm bớt sự cố.
Có một số ví dụ điển hình về những gì có ý nghĩa không?
Câu trả lời:
Cập nhật tháng 5 năm 2013: tài liệu chính thức có trong phần " Tổ chức mã "
Mã Go phải được giữ trong không gian làm việc .
Không gian làm việc là một hệ thống phân cấp thư mục với ba thư mục ở gốc:
src
chứa các tệp nguồn Go được tổ chức thành các gói (một gói cho mỗi thư mục),pkg
chứa các đối tượng gói vàbin
chứa các lệnh thực thi.Các
go tool
gói nguồn xây dựng và cài đặt các tệp nhị phân kết quả vào thư mụcpkg
vàbin
.Thư
src
mục con thường chứa nhiều kho lưu trữ kiểm soát phiên bản (chẳng hạn như cho Git hoặc Mercurial) theo dõi sự phát triển của một hoặc nhiều gói nguồn.
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
Cập nhật tháng 7 năm 2014: xem " Cấu trúc ứng dụng đang hoạt động " từ Ben Johnson
Bài viết đó bao gồm các mẹo như:
kết hợp
main.go
tệp và logic ứng dụng của tôi trong cùng một gói có hai hệ quả:
- Nó làm cho ứng dụng của tôi không sử dụng được như một thư viện.
- Tôi chỉ có thể có một ứng dụng nhị phân.
Cách tốt nhất tôi đã tìm ra để khắc phục điều này là chỉ cần sử dụng một
cmd
thư mục “” trong dự án của tôi, nơi mỗi thư mục con của nó là một tệp nhị phân ứng dụng.
camlistore/
cmd/
camget/
main.go
cammount/
main.go
camput/
main.go
camtool/
main.go
Di chuyển
main.go
tệp ra khỏi thư mục gốc của bạn cho phép bạn xây dựng ứng dụng của mình từ quan điểm của một thư viện. Hệ nhị phân ứng dụng của bạn chỉ đơn giản là một ứng dụng khách của thư viện ứng dụng của bạn.Đôi khi bạn có thể muốn người dùng tương tác theo nhiều cách nên bạn tạo nhiều tệp nhị phân.
Ví dụ: nếu bạn cóadder
gói “” cho phép người dùng cộng các số lại với nhau, bạn có thể muốn phát hành phiên bản dòng lệnh cũng như phiên bản web.
Bạn có thể dễ dàng làm điều này bằng cách tổ chức dự án của mình như sau:
adder/
adder.go
cmd/
adder/
main.go
adder-server/
main.go
Người dùng có thể cài đặt các tệp nhị phân ứng dụng “adder” của bạn với “go get” bằng cách sử dụng dấu ba chấm:
$ go get github.com/benbjohnson/adder/...
Và thì đấy, người dùng của bạn đã cài đặt “
adder
” và “adder-server
”!
Thông thường, các loại dự án của tôi đều rất liên quan nên nó phù hợp hơn từ quan điểm về khả năng sử dụng và API.
Những loại này cũng có thể tận dụng lợi thế của việc gọi chưa được báo cáo giữa chúng, giúp API nhỏ và rõ ràng.
- Nhóm các loại và mã liên quan lại với nhau trong mỗi tệp. Nếu các loại và chức năng của bạn được tổ chức tốt thì tôi thấy rằng các tệp có xu hướng nằm trong khoảng từ 200 đến 500 SLOC. Điều này nghe có vẻ nhiều nhưng tôi thấy rất dễ điều hướng. 1000 SLOC thường là giới hạn trên của tôi cho một tệp.
- Sắp xếp loại quan trọng nhất ở đầu tệp và thêm các loại theo mức độ quan trọng giảm dần về phía cuối tệp.
- Khi ứng dụng của bạn bắt đầu đạt trên 10.000 SLOC, bạn nên nghiêm túc đánh giá xem nó có thể được chia thành các dự án nhỏ hơn hay không.
Lưu ý: thực hành cuối cùng không phải lúc nào cũng tốt:
Xin lỗi tôi chỉ không thể đồng ý với thực hành này.
Việc tách loại thành tệp giúp quản lý mã, khả năng đọc, khả năng bảo trì, khả năng kiểm tra.
Nó cũng có thể đảm bảo trách nhiệm duy nhất và tuân theo nguyên tắc mở / đóng…
Quy tắc không cho phép phụ thuộc vòng tròn là buộc chúng ta phải có cấu trúc rõ ràng của các gói.
(Thay thế vào tháng 2 năm 2013, src
chỉ liên quan đến )
Bạn có thể tìm thấy bố cục cổ điển được minh họa trong " Bố cục mã GitHub ":
Ứng dụng và cả hai thư viện đều có trên Github, mỗi thư viện nằm trong kho riêng của nó.
$GOPATH
là thư mục gốc của dự án - mỗi repo Github của bạn sẽ được kiểm tra một số thư mục bên dưới$GOPATH
.Bố cục mã của bạn sẽ giống như sau:
$GOPATH/
src/
github.com/
jmcvetta/
useless/
.git/
useless.go
useless_test.go
README.md
uselessd/
.git/
uselessd.go
uselessd_test.go
README.md
Mỗi thư mục bên dưới
src/github.com/jmcvetta/
là thư mục gốc của một bản kiểm tra git riêng biệt.
Tuy nhiên, điều đó đã thu hút một số lời chỉ trích, trong trang reddit này :
Tôi thực sự khuyên bạn không nên cấu trúc repo theo cách bạn có, nó sẽ bị hỏng "
go get
", đây là một trong những điều hữu ích nhất về cờ vây.
Tốt hơn là viết mã của bạn cho những người biết cờ vây, vì họ rất có thể là người biên dịch nó.
Và đối với những người không, ít nhất họ sẽ có cảm giác với ngôn ngữ.Đặt gói chính vào thư mục gốc của repo.
Đặt các tài sản trong một thư mục con (để giữ mọi thứ gọn gàng).
Giữ phần thịt của mã trong một gói con (trong trường hợp bất kỳ ai muốn sử dụng lại nó bên ngoài tệp nhị phân của bạn).
Bao gồm tập lệnh thiết lập trong thư mục gốc của repo để dễ dàng tìm thấy.Nó vẫn chỉ là một quá trình hai bước để tải xuống, xây dựng, cài đặt và thiết lập:
- "
go get <your repo path>
": tải xuống và cài đặt mã go, với mã phụ cho nội dung$GOPATH/<your repo path>/setup.sh
: phân phối tài sản đến đúng nơi và cài đặt dịch vụ
Tôi giả định rằng với 'dự án' bạn không có nghĩa là một gói Go mà là một phần mềm bạn phát triển. Nếu không, bạn có thể nhận trợ giúp ở đây và ở đây . Tuy nhiên, cách viết các gói cho Go không khác quá nhiều: Sử dụng các gói, tạo một thư mục cho mỗi gói và kết hợp các gói đó trong ứng dụng của bạn.
Để xây dựng ý kiến cho mình, bạn có thể xem kho lưu trữ thịnh hành của Go trên github: https://github.com/trending/go . Ví dụ đáng chú ý là cayley và zeus .
Sơ đồ phổ biến nhất có lẽ là có một tệp Go chính và nhiều mô-đun và mô-đun con trong thư mục riêng của chúng. Trong trường hợp bạn có nhiều tệp meta (doc, giấy phép, các mẫu, ...), bạn có thể muốn đặt mã nguồn vào một thư mục con. Đó là những gì tôi đã làm cho đến nay.
$GOPATH/src
hoặc sử dụng họ go get
tên bảng được.
doozerd
không phải là một ví dụ tốt, ngay cả các bài kiểm tra của nó cũng yếu.
Có một cách tiếp cận được đề xuất từ các tác giả của Golang xác định cách bố trí mã của bạn để hoạt động tốt nhất với các công cụ go và hỗ trợ hệ thống kiểm soát nguồn
$GOROOT
, không phải mã trong src/<project>
thư mục.
Bạn có lẽ cũng nên xem qua repo này. Nó cho thấy rất nhiều ý tưởng về cách cấu trúc các ứng dụng go: https://github.com/golang-standards/project-layout
setup.sh
là Go hợp lý đa nền tảng trong khi các tập lệnh shell POSIX thì không.