Các vấn đề với việc tránh các lớp đặt tên Smurf với không gian tên


39

Tôi lấy thuật ngữ đặt tên smurf từ đây (số 21). Để cứu bất kỳ ai không quen thuộc với rắc rối, đặt tên Smurf là ​​hành động tiền tố một loạt các lớp, biến, v.v. có tiền tố chung để bạn kết thúc bằng "a SmurfAccountViewpass a SmurfAccountDTOto the SmurfAccountController", v.v.

Giải pháp tôi thường nghe nói đến là tạo một không gian tên smurf và bỏ các tiền tố smurf. Điều này thường phục vụ tốt cho tôi, nhưng tôi đang gặp phải hai vấn đề.

  1. Tôi đang làm việc với một thư viện với một Configurationlớp học. Nó có thể được gọi WartmongerConfigurationnhưng nó nằm trong không gian tên Wartmonger, vì vậy nó chỉ được gọi Configuration. Tôi cũng có một Configurationlớp có thể được gọi SmurfConfiguration, nhưng nó nằm trong không gian tên Smurf nên sẽ không cần thiết. Có những vị trí trong mã của tôi Smurf.Configurationxuất hiện dọc theo Wartmonger.Configurationvà gõ ra các tên đủ điều kiện là khó hiểu và làm cho mã ít đọc hơn. Sẽ tốt hơn khi xử lý một SmurfConfigurationvà (nếu đó là mã của tôi chứ không phải thư viện) WartmongerConfiguration.

  2. Tôi có một lớp được gọi Servicetrong không gian tên Smurf của tôi có thể được gọi SmurfService. Servicelà một mặt tiền trên đỉnh của một thư viện Smurf phức tạp chạy các công việc Smurf. SmurfServicecó vẻ như là một cái tên tốt hơn bởi vì Servicekhông có tiền tố Smurf thì rất chung chung. Tôi có thể chấp nhận rằng đó SmurfServiceđã là một cái tên chung chung, vô dụng và lấy đi smurf chỉ làm cho điều này trở nên rõ ràng hơn. Nhưng nó có thể được đặt tên Runner, Launcherv.v. và nó vẫn sẽ "cảm thấy tốt hơn" đối với tôi SmurfLaunchervì tôi không biết những gì Launcherlàm, nhưng tôi biết những gì SmurfLauncherlàm. Bạn có thể lập luận rằng những gì Smurf.Launcherkhông nên làm rõ ràng như mộtSmurf.SmurfLauncher, nhưng tôi có thể thấy `Smurf.Launcher là một loại lớp liên quan đến thiết lập chứ không phải là một lớp khởi chạy smurfs.

Nếu có một cách mở và đóng để đối phó với một trong những điều đó sẽ là tuyệt vời. Nếu không, một số thực tiễn phổ biến để giảm bớt sự khó chịu của họ là gì?


3
Smurf.Launcherkhởi chạy smurfs, hoặc nó khởi chạy SmurfJobs? Có lẽ nó có thể được gọi là Smurf.JobLauncher?
Blorgbeard

2
Đó là một mùi mã để đặt tên cho một lớp XService, XManager, v.v. Những thứ này không có nghĩa gì cả. Nó giống như một Util. Nếu bạn lướt qua tên tệp, mọi thứ có thể ở đó hoặc bị thiếu ở đó. Không có cách nào để biết trừ khi bạn nhìn vào bên trong. Tôi đã đổi tên nó từ SmurfService thành một cái gì đó hoàn toàn khác.
Daniel Kaplan

1
Nó thực sự khởi chạy SmurfJobs, hoặc về mặt kỹ thuật chạy chúng để phù hợp với ngôn ngữ của tài liệu Smurf. Trong bối cảnh đó và các câu trả lời khác, tôi sẽ đổi tên SmurfServicethành SmurfJobRunner. Có vẻ như số 1 không có giải pháp tốt nhất về ngôn ngữ bất khả tri như tôi mong đợi. Tôi có thể thấy các trường hợp đi cùng SmurfConfigurationsẽ là cuộc gọi đúng, nhưng trong trường hợp của tôi, tôi nghĩ Configurationlà tốt nhất ngay cả với những rắc rối Wartmonger.Configuration.
Daniel Koverman

6
Tôi đang cố gắng hiểu lý do tại sao bạn có một lớp duy nhất quan tâm đến việc định cấu hình cả Wartmongers và Smurfs.
Donal Fellows

Tại sao làm Smurf.ConfigurationSmurfConfigurationcảm thấy khác nhau? Chắc chắn đó không phải là char thêm, phải không? (Rút ngắn xuống Confignếu độ dài là vấn đề.) Có Smurf.Configurationvấn đề SmurfConfigurationnào không?
Pablo H

Câu trả lời:


16

Bạn nêu lên một số điểm tốt.

  1. Liên quan đến việc có các lớp trùng lặp, bạn có thể bí danh các lớp trong C #. Sử dụng ví dụ using ColorScheme = The.Fully.Qualified.Namespace.Outlook2007ColorScheme;Xem bài đăng này trên StackOverflow . Bạn đã không chỉ ra ngôn ngữ lập trình của bạn nhưng tôi đã suy luận nó từ những gì bạn đã viết. Vì vậy, khi bạn đang làm việc với hai dự án khác nhau, bạn có thể đặt bí danh cho chúng SmurfConfigurationWartmongerConfigurationđiều này sẽ giải phóng sự mơ hồ khi tiêu thụ cả hai lớp.

  2. Vì một dịch vụ được tiếp xúc với (các) ứng dụng bên ngoài, tôi thấy không có vấn đề gì trong việc xây dựng thương hiệu dịch vụ với tên ứng dụng của bạn, vì vậy trong trường hợp này SmurfServicesẽ hợp lệ vì nó thực sự sẽ phân tán các nhóm dịch vụ trong ứng dụng tiêu dùng.

Tôi cảm thấy rằng không gian tên nên được sử dụng để tránh kiểu đặt tên này. Điều này làm cho việc tìm kiếm mã trở nên khó khăn hơn và xem giá trị của một lớp mà không cần đọc MyCompanyMy SẢNtMyAreaClassName. Sử dụng kỹ thuật răng cưa cho phép bạn giảm sự mơ hồ khi cần thiết. Lần duy nhất tôi nghĩ bạn nên giới thiệu sự phức tạp trong cách đặt tên của mình là, như tôi đã chỉ ra ở mục số 2, khi mọi người sẽ sử dụng một dịch vụ. Đây là nơi có ý nghĩa hoàn hảo để có phong cách đặt tên này bởi vì nếu người tiêu dùng có nhiều dịch vụ khác nhau thì việc tiêu thụ có thể gây nhầm lẫn.


5
bí danh chỉ làm rối tung mọi thứ lên. Thay vì Smurf.Service bây giờ bạn có SmurfService = Smurf.Service. Vì vậy, bạn cũng có thể đã có SmurfService là tên của sự vật ở nơi đầu tiên. Họ có một nơi, nhưng không phải cho vấn đề đặc biệt này. Tuy nhiên, đây có lẽ là câu trả lời tốt nhất cho một vấn đề không có câu trả lời :)
gbjbaanb

. C # trong tôi xuất hiện trong câu hỏi của tôi, nhưng tôi thực sự hiện đang làm việc với java và org.apache.smurfville.wartmonger.configuration. Điều này không may loại trừ bí danh. 2 là một điểm vững chắc, vì vậy tôi sẽ tiếp tục xây dựng thương hiệu Smurf cho Dịch vụ.
Daniel Koverman

25

Điểm của không gian tên là để bạn có thể có các lớp cùng tên từ các thư viện khác nhau mà không có chúng va chạm. Khi bạn cần sử dụng cùng một lớp được đặt tên từ cả hai, bạn cần loại bỏ sự mơ hồ bằng cách thêm tiền tố vào một hoặc cả hai với phạm vi không gian tên của nó.

Điều đó nói rằng, thật không tệ khi có một loạt các lớp Smurf nếu Smurf cho bạn biết điều gì đó cụ thể về lớp học. Tên lớp phải đủ mô tả để cung cấp cho bạn một số thông tin về những gì lớp học làm.

      Session
       ^   ^
      /     \
DBSession   HttpSession

Tương tự như vậy DBSessioncó thể lấy một DBRequestđối tượng trả về một DBResponseđối tượng. Cũng HttpSessioncó thể hoạt động trên HttpRequestHttpResponsecác đối tượng.

Đây là những lớp Smurf có mục đích.

Họ có thể sống trong MyCompanykhông gian tên nhưng MyCompanyHttpSessionMyCompanyDBSessionkhông cung cấp cho bạn bất kỳ thông tin nhiều hơn bạn có trước đây. Trong trường hợp này, thả Smurf và biến nó thành một không gian tên.

MyCompany.HttpSession

3

Trước đây tôi đã từng gặp phải sự nhầm lẫn tương tự này và đây thực sự là một câu hỏi liệu chúng ta có bao gồm loại điều mà nó là một phần của tên của nó không.

Bạn đề cập SmurfConfigurationWartmongerConfigurationnhư các loại cấu hình tiềm năng. Bạn chỉ ra rằng bạn đã loại bỏ tính từ (loại của nó) vào không gian tên của nó để những gì bạn còn lại chỉ là vanilla Configuration. Tôi sẽ tránh làm điều đó.

Nó giống như quyết định rằng kem dâu tây chỉ là kem trong không gian tên dâu tây và tương tự như vậy với sô cô la, nhưng điều xảy ra là bạn đã ly dị tính từ mang lại bản sắc của nó từ chính nó. Nó không phải là kem trong danh mục dâu tây. Đó là kem dâu tây - một loại kem.

Hãy tưởng tượng rằng trong ứng dụng của bạn, bạn nhập Strawberry.IceCreamlớp và sau đó bắt đầu khởi tạo trực tiếp từ đó IceCream.

var ic = new IceCream(); //actually I'm strawberry ice cream

Điều này có vẻ tốt và tốt, cho đến khi bạn kết thúc việc nhập một IceCreamlớp khác . Bây giờ bạn trở lại vấn đề ban đầu là phải bằng cách nào đó phân biệt giữa chúng, đó là vấn đề. Những gì bạn muốn tất cả cùng là:

var sic = new StrawberryIceCream();
var cic = new ChocolateIceCream();

Không gian tên tốt hơn để tránh xung đột tiềm ẩn giữa các bên thứ ba, những người có thể tình cờ đại diện cho các khái niệm tương tự trong thư viện của họ. Tuy nhiên, khi một nhà phát triển tạo ra một thư viện hoặc dự án, anh ta nên đặt tên cho từng khái niệm duy nhất và chỉ sử dụng các không gian tên làm thư mục cho tổ chức. Thường thì tên của thư mục sẽ được tìm thấy trong tên của các khái niệm mà nó tổ chức và không sao cả.


2

Đó chắc chắn là một quy tắc tốt nếu bạn có tiền tố chung trên một loạt các lớp, thì có lẽ họ xứng đáng được đi trong không gian tên của riêng họ. Để giải quyết vấn đề sau đó, khi bạn cần sử dụng các lớp được đặt tên tương tự từ hai không gian tên:

1) Bí danh các không gian tên, mặc dù tôi muốn viết ngắn gọn và đến mức, bất kỳ chữ viết tắt tự nhiên nào, thậm chí có thể chỉ 1 chữ cái:

using Sm = Smurf;
using W = Wartmonger;

Sau đó, luôn luôn tiền tố bất cứ nơi nào được sử dụng và đặt tên thích hợp:

Sm::Configuration smConf; 
W::Configuration wConf;

2) Bí danh lớp, như được đề xuất trong câu trả lời khác.

using SmConf = Smurf.Configuration;

3) Bất kỳ thư viện nào bạn có quyền kiểm soát, hãy cân nhắc việc không sử dụng thuật ngữ 'Cấu hình'. Sử dụng từ điển đồng nghĩa: ví dụ 'Cài đặt', 'Kiểu', 'Thông số'. Dù sao cũng có thể có ý nghĩa hơn đối với bối cảnh: Ví dụ: nếu Smurf là ​​một loại mô-đun phân tích số mà bạn đã viết có lẽ 'Thông số' sẽ tốt hơn cho cấu hình của nó. Sử dụng từ vựng cụ thể được liên kết với ngữ cảnh của mô-đun để lợi thế của bạn để đưa ra các tên duy nhất giữ tính duy nhất ngay cả khi trộn lẫn vào các không gian tên khác. Tôi cảm thấy đây có thể là một câu trả lời cho câu hỏi OP 2.

4) Mã tái cấu trúc để bạn không phải trộn lẫn việc sử dụng cấu hình từ hai nơi khác nhau. Chi tiết về điều đó là tùy thuộc vào bạn.

5) Kết hợp hai cấu hình thành một trước khi bạn chuyển nó vào lớp của bạn. Sử dụng một lớp conf kết hợp để đại diện:

struct Conf {
    SmurfConfiguration smurf;
    WartmongerConfiguation wart;
}

Các tên biến thành viên ngắn hiện đang đạt được điều tương tự như đặt bí danh cho lớp / không gian tên.


0

Có vẻ lạ khi thêm một điểm vào tên làm phiền bạn.

Wartmonger.Configuration configuration = Wartmonger.Configuration .new();

// vs

WartmongerConfiguration configuration = WartmongerConfiguration.new();

Nếu cả hai SmurfWartmongercấu hình được sử dụng cùng một nơi, nhưng riêng biệt chúng được sử dụng ở nhiều nơi - thì không gian tên chắc chắn là cách tiếp cận tốt.

Có namespace sẽ cung cấp khả năng sử dụng tên "sạch" trong mã nội bộ, nơi có tiền tố bạn kết thúc sử dụng SmurfConfigurationbên trong SmurfServicecủa mã nội bộ, có thể trở thành khó chịu mỗi lần bạn sẽ mở mã.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.