Nếu tôi tiếp tục viết thêm mã thì sẽ có lúc tôi gặp khó khăn trong việc tổ chức mã.
Đây là vấn đề của bạn: làm cho tổ chức phù hợp và phong cách sẽ dễ dàng trôi chảy hơn.
Đừng chờ đợi để tổ chức mã của bạn: giữ cho mã của bạn được tổ chức khi bạn đi. Mặc dù ngôn ngữ không làm điều đó cho bạn, mã vẫn nên được tổ chức thành các mô-đun với độ khớp thấp và độ gắn kết cao.
Các mô-đun sau đó tự nhiên cung cấp một không gian tên. Viết tắt tên mô-đun (nếu dài) và tên hàm tiền tố với mô-đun của chúng để tránh va chạm.
Ở cấp độ định danh cá nhân, đây là khoảng thứ tự tăng tính chủ quan:
- chọn một quy ước và gắn bó với nó
- ví dụ,
function_like_this(struct TypeLikeThis variable)
là phổ biến
chắc chắn tránh ký hiệu Hungary (xin lỗi JNL)
trừ khi bạn sẵn sàng sử dụng nó như dự định ban đầu, điều đó có nghĩa là ký hiệu ứng dụng của Simony thay vì phiên bản hệ thống khủng khiếp
Tại sao? Tôi có thể viết một bài luận về điều này, nhưng thay vào đó tôi sẽ đề nghị bạn đọc bài viết này của Joel Spolsky, và sau đó săn lùng thêm một số nếu bạn quan tâm. Có một liên kết đến giấy gốc của Simonyi ở phía dưới.
tránh con trỏ typedefs trừ khi chúng thực sự là loại cookie mờ - chúng chỉ gây nhầm lẫn mọi thứ
struct Type *ok;
typedef struct Type *TypePtr;
TypePtr yuck;
Ý tôi là gì bởi một loại cookie mờ ? Ý tôi là một cái gì đó được sử dụng bên trong một mô-đun (hoặc thư viện hoặc bất cứ thứ gì) phải được chuyển cho mã máy khách, nhưng mã máy khách đó không thể sử dụng trực tiếp. Nó chỉ cần chuyển nó trở lại thư viện.
Ví dụ: thư viện cơ sở dữ liệu có thể hiển thị giao diện như
/* Lots of buffering, IPC and metadata magic held in here.
No, you don't get to look inside. */
struct DBContextT;
/* In fact, you only ever get a pointer, so let's give it a nice name */
typedef struct DBContexT *DBContext;
DBContext db_allocate_context(/*maybe some optional flags?*/);
void db_release_context(DBContext);
int db_connect(DBContext, const char *connect);
int db_disconnect(DBContext);
int db_execute(DBContext, const char *sql);
Bây giờ, bối cảnh mờ đục đối với mã máy khách, vì bạn không thể nhìn vào bên trong. Bạn chỉ cần chuyển nó trở lại thư viện. Một cái gì đó giống như FILE
là mờ đục, và một mô tả tập tin số nguyên cũng là một cookie , nhưng không phải là mờ.
Một lưu ý về thiết kế
Tôi đã sử dụng cụm từ khớp nối thấp và độ gắn kết cao ở trên mà không có lời giải thích, và tôi cảm thấy một chút xấu về điều đó. Bạn có thể tìm kiếm nó và có thể tìm thấy một số kết quả tốt, nhưng tôi sẽ cố gắng giải quyết ngắn gọn (một lần nữa, tôi có thể viết một bài luận nhưng sẽ cố gắng không).
Thư viện DB được phác thảo ở trên cho thấy khả năng ghép thấp vì nó phơi bày một giao diện nhỏ với thế giới bên ngoài. Bằng cách ẩn các chi tiết triển khai của nó (một phần với thủ thuật cookie mờ), nó ngăn chặn mã máy khách đến phụ thuộc vào các chi tiết đó.
Hãy tưởng tượng thay vì cookie mờ, chúng tôi khai báo cấu trúc bối cảnh để nội dung của nó hiển thị và bao gồm một mô tả tệp ổ cắm cho kết nối TCP đến cơ sở dữ liệu. Nếu sau đó chúng tôi thay đổi việc triển khai để hỗ trợ sử dụng phân đoạn bộ nhớ dùng chung khi DB đang chạy trên cùng một máy, máy khách cần được biên dịch lại thay vì chỉ được liên kết lại. Thậm chí tệ hơn, máy khách có thể đã bắt đầu sử dụng bộ mô tả tệp, ví dụ như gọi setsockopt
để thay đổi kích thước bộ đệm mặc định và bây giờ nó cũng cần thay đổi mã. Tất cả các chi tiết này nên được ẩn bên trong mô-đun của chúng tôi, nơi thực tế và điều này mang lại sự khớp nối thấp giữa các mô-đun.
Ví dụ này cũng cho thấy sự gắn kết cao , trong đó tất cả các phương thức trong mô-đun đều liên quan đến cùng một tác vụ (truy cập DB). Điều này có nghĩa là chỉ có mã cần biết về các chi tiết triển khai (nghĩa là nội dung của cookie của chúng tôi) thực sự có quyền truy cập vào chúng, giúp đơn giản hóa việc gỡ lỗi.
Bạn cũng có thể thấy rằng có một mối quan tâm duy nhất giúp bạn dễ dàng chọn tiền tố để nhóm các chức năng này lại với nhau.
Bây giờ, nói ví dụ này là tốt là dễ dàng (đặc biệt là vì nó thậm chí chưa hoàn thành), nhưng ngay lập tức không giúp bạn. Mẹo nhỏ là hãy xem, khi bạn viết và mở rộng mã của mình, cho các hàm làm những việc tương tự hoặc hoạt động trên cùng loại (có thể là ứng cử viên cho mô-đun của riêng chúng) và cũng cho các hàm thực hiện nhiều điều riêng biệt phát sinh ' t thực sự liên quan, và có thể là ứng cử viên để chia tách.