it-swarm-vi.com

Thực hành tốt nhất để sử dụng không gian tên trong C ++

Tôi đã đọc chú Bob Mã sạch vài tháng trước, và nó đã có tác động sâu sắc đến cách tôi viết mã. Ngay cả khi có vẻ như anh ta đang lặp lại những điều mà mọi lập trình viên nên biết, đặt tất cả chúng lại với nhau và đưa chúng vào thực tế sẽ dẫn đến mã sạch hơn nhiều. Cụ thể, tôi thấy việc chia các hàm lớn thành nhiều hàm nhỏ và chia các lớp lớn thành nhiều lớp nhỏ trở nên vô cùng hữu ích.

Bây giờ cho câu hỏi. Các ví dụ của cuốn sách đều bằng Java, trong khi tôi đã làm việc trong C++ trong nhiều năm qua. Làm thế nào các ý tưởng trong Clean Code sẽ mở rộng đến việc sử dụng các không gian tên không tồn tại trong Java? (Vâng, tôi biết về các gói Java, nhưng nó không thực sự giống nhau.)

Liệu nó có ý nghĩa để áp dụng ý tưởng tạo ra nhiều thực thể nhỏ, mỗi thực thể có trách nhiệm được xác định rõ ràng, cho các không gian tên? Một nhóm nhỏ các lớp liên quan có nên luôn được bọc trong một không gian tên? Đây có phải là cách để quản lý sự phức tạp của việc có nhiều lớp nhỏ, hoặc chi phí quản lý nhiều không gian tên sẽ bị cấm?

Chỉnh sửa: Câu hỏi của tôi được trả lời trong mục này mục nhập Wikipedia về Nguyên tắc Gói .

39
Dima

(Tôi chưa đọc Mã sạch và không biết nhiều về Java.)

Liệu nó có ý nghĩa để áp dụng ý tưởng tạo ra nhiều thực thể nhỏ, mỗi thực thể có trách nhiệm được xác định rõ ràng, cho các không gian tên?

Vâng, giống như nó làm với tái cấu trúc thành nhiều lớp và nhiều hàm.

Một nhóm nhỏ các lớp liên quan có nên luôn được bọc trong một không gian tên?

Không thực sự trả lời: có, ít nhất bạn nên sử dụng một không gian tên cấp cao nhất. Điều này có thể dựa trên dự án, tổ chức hoặc bất cứ điều gì bạn thích, nhưng sử dụng một vài tên toàn cầu sẽ làm giảm xung đột tên. Một không gian tên duy nhất để nhóm mọi thứ khác theo nó chỉ giới thiệu một tên toàn cầu. (Ngoại trừ các chức năng "C" bên ngoài, nhưng đó là do khả năng tương tác của C và chỉ ảnh hưởng đến các chức năng "C" bên ngoài khác.)

Một nhóm nhỏ các lớp liên quan có nên được bọc trong một không gian tên dành riêng cho chúng không? Có lẽ. Đặc biệt nếu bạn thấy mình sử dụng tiền tố phổ biến trên các lớp đó - FrobberT Breath, FrobberThang, FrobberDoohickey - bạn nên xem xét một không gian tên - frobber :: Thing, v.v. Điều này vẫn sẽ nằm trong không gian tên gốc của bạn hoặc không gian tên khác nếu chúng là một phần của dự án lớn hơn.

Đây có phải là cách để quản lý sự phức tạp của việc có nhiều lớp nhỏ, hoặc chi phí quản lý nhiều không gian tên sẽ bị cấm?

Lấy ví dụ trên về tên tiền tố, việc quản lý frobber :: Thing so với FrobberThing không khó hơn. Nó thậm chí có thể dễ dàng hơn với một số công cụ, chẳng hạn như hoàn thành tài liệu và mã. Có một sự khác biệt với ADL, nhưng điều này có thể có lợi cho bạn: ít tên trong các không gian tên được liên kết làm cho ADL đơn giản hơn để tìm ra và bạn có thể sử dụng khai báo để tiêm tên cụ thể vào không gian tên này hoặc không gian tên khác.

Bí danh không gian tên cho phép bạn sử dụng tên ngắn hơn cho không gian tên dài hơn trong ngữ cảnh cụ thể, điều này một lần nữa cho phép sử dụng dễ dàng hơn:

void f() {
  namespace CWVLN = Company_with_very_long_name;  // Example from the standard.
  // In this scope, use CWVLN::name instead of Company_with_very_long_name::name.
  namespace fs = boost::filesystem;  // Commonly used.
}

Hãy xem xét Boost, có một không gian tên gốc duy nhất, boost, và sau đó là nhiều tên con - boost :: asio, boost :: io, boost :: filesystem, boost :: tuples, v.v. - cho các thư viện khác nhau. Một số tên được "thăng cấp" vào không gian tên gốc:

Tất cả các định nghĩa đều nằm trong không gian tên :: boost :: tuples, nhưng các tên phổ biến nhất được nâng lên không gian tên :: boost bằng cách sử dụng khai báo. Những tên này là: Tuple, make_Tuple, tie và get. Hơn nữa, ref và cref được định nghĩa trực tiếp trong không gian tên :: boost.

Sự khác biệt lớn nhất so với các ngôn ngữ với các mô-đun "thực" là mức độ phổ biến của việc sử dụng cấu trúc phẳng hơn, điều này chủ yếu xảy ra vì đó là cách nó hoạt động trừ khi bạn mất thêm nỗ lực cụ thể để xác định tên lồng nhau.

23
Fred Nurk

Bạn nên có một không gian tên chính cho tất cả mã của bạn. Điều này phân biệt nó với mã bên ngoài liên quan đến không gian tên.

Trong không gian tên chính của bạn, tùy thuộc vào kích thước và độ phức tạp, bạn có thể mở các không gian tên phụ. Đây là nơi các tên rõ ràng có nghĩa là một cái gì đó trong một bối cảnh và các tên tương tự có thể được sử dụng trong một bối cảnh khác.

Cụ thể, nếu bạn có một tên âm chung như FileInfo có nghĩa là một cái gì đó cụ thể trong một ngữ cảnh, hãy đặt nó trong một không gian tên.

Bạn cũng có thể sử dụng một lớp cho việc này, mặc dù một lớp không thể mở rộng để bạn không thể thêm các khai báo mới vào lớp mà không sửa đổi tiêu đề của nó.

9
CashCow

Không gian tên không phải là một khái niệm Mô-đun, vì vậy tôi sẽ chỉ sử dụng chúng khi có thể xảy ra xung đột tên.

3
Brainlag

Tôi thích không gian tên sâu (thường có nghĩa là ba cấp độ).

  • Tôi có tên công ty.
  • ứng dụng/produc/lib/etc
  • Tên dự án/hoặc Gói phù hợp

Tùy thuộc vào tình huống tôi có thể có thêm một cấp độ

  • chi tiết (Chi tiết triển khai cụ thể nền tảng)
  • utils (đối tượng tiện ích chưa được chuyển sang tiện ích chung).
  • bất cứ điều gì tôi cần.
1
Martin York

Java có các không gian tên, chúng thực sự không được gọi như vậy. Trong javax.swing.*javax là một không gian tên và swing là một không gian tên phụ. Tôi chưa đọc cuốn sách để biết những gì nó nói về Java, nhưng các nguyên tắc tương tự sẽ áp dụng khá nhiều trực tiếp vào không gian tên trong bất kỳ ngôn ngữ nào.

Một heuristic tốt là bạn sử dụng một không gian tên khi bạn thấy mình muốn gõ cùng một tiền tố cho các lớp nhiều lần. Ví dụ, gần đây tôi đã viết một số lớp gọi là OmciAttribution, OmciAlarm, OmciMe, v.v. và nhận ra rằng tôi cần phải chia Omci vào không gian tên của chính nó.

1
Karl Bielefeldt