Làm thế nào để tránh tên chung cho các lớp trừu tượng?


10

Nói chung, tốt nhất là tránh các từ như "xử lý" hoặc "xử lý" như một phần của tên thường trình và tên lớp, trừ khi bạn đang xử lý (ví dụ) xử lý tệp hoặc (ví dụ) các quy trình unix. Tuy nhiên, các lớp trừu tượng thường không thực sự biết họ sẽ làm gì với thứ gì đó bên cạnh, nói, xử lý nó. Trong tình huống hiện tại của tôi, tôi có một "Trình xử lý email" đăng nhập vào hộp thư đến của người dùng và xử lý các tin nhắn từ nó. Tôi không thực sự rõ ràng làm thế nào để đặt tên này chính xác hơn, mặc dù tôi đã nhận thấy vấn đề phong cách sau đây phát sinh:

  • tốt hơn để coi các lớp dẫn xuất là các máy khách và đặt tên lớp cơ sở theo một phần của chức năng mà nó thực hiện? Cung cấp cho nó nhiều ý nghĩa hơn nhưng sẽ vi phạm is-a. Ví dụ: EmailAcquirer sẽ là một cái tên hợp lý vì nó có được lớp dẫn xuất, nhưng lớp dẫn xuất sẽ không được mua cho bất kỳ ai.
  • Hoặc chỉ là tên thực sự mơ hồ vì ai biết các lớp dẫn xuất sẽ làm gì. Tuy nhiên "Bộ xử lý" vẫn còn quá chung chung vì nó thực hiện nhiều hoạt động liên quan, như đăng nhập và sử dụng IMAP.

Có cách nào thoát khỏi tình trạng khó xử này không?

Vấn đề rõ ràng hơn đối với các phương pháp trừu tượng, trong đó bạn thực sự không thể trả lời câu hỏi "cái này làm gì?" bởi vì câu trả lời chỉ đơn giản là "bất cứ điều gì khách hàng muốn."


Bạn có nguồn (và một số bối cảnh) cho yêu cầu "nói chung" đó không? Ngoài ra, một quy tắc đặt tên bổ sung cho danh sách - đừng lãng phí thời gian để tìm kiếm một cái tên hoàn hảo có lẽ không tồn tại. Nếu nghi ngờ, hãy đặt tên tốt nhất bạn có thể, thêm mô tả dài hơn dưới dạng nhận xét nếu cần, nhưng bạn luôn có thể cấu trúc lại sau nếu ai đó không thích lựa chọn của bạn hoặc tên hoàn hảo bất ngờ xảy ra với bạn khi bạn ' Đang làm một cái gì đó khác.
Steve314

3
@ Steve314 - có, Steve McConnell, Code Complete, lần xuất bản thứ nhất, Chương 4 hoặc 5 về thói quen. Thảo luận rộng rãi về cách đặt tên trong các chương này, về cơ bản là kết luận nếu bạn không có tên hay thì có lẽ bạn không có chức năng tốt.
djechlin

Không tìm thấy một tên tốt có vẻ như là một dấu hiệu xấu, nhưng IMO bạn nên biết nếu chức năng đó là xấu dựa trên chính chức năng đó. Tái cấu trúc chỉ vì ngôn ngữ tiếng Anh không được thiết kế tùy chỉnh cho dự án của bạn là một chút sai lầm. Không, đó không phải là vấn đề hàng ngày, nhưng bạn đã quyết định rằng bạn có vấn đề.
Steve314

1
@ Steve314 Lập trình hoàn toàn là về việc quản lý sự phức tạp và nếu bộ não của bạn không thể đưa ra một từ nào cho một thứ gì đó thì rất có thể nó sẽ không thể quản lý sự phức tạp của nó khi nó phải làm những việc như sử dụng nó câu lớn hơn hoặc là một phần của hệ thống lớn hơn. Đó thực sự không phải là một tuyên bố táo bạo để nói rằng không thể tìm thấy một tên tốt là một nguyên nhân lớn để tạm dừng cho mối quan tâm. Nhưng điều này được thảo luận rộng rãi trong McConnell, tôi khuyên bạn nên đọc ít nhất hai chương đó mặc dù toàn bộ cuốn sách đáng để đọc từ trang bìa.
djechlin

các yêu cầu trong Code Complete không nhất thiết phải được tin cậy. Tôi biết về danh tiếng sách, nhưng tôi cũng nhận thức được điều này . Bên cạnh đó, tôi đã quản lý sự phức tạp hoàn toàn tốt cho các lứa tuổi - lỗi xảy ra, của couse, nhưng khi có sự cố xảy ra, đôi khi vấn đề là một chức năng đơn giản đến mức rõ ràng không thể sai, nhưng dù sao đi nữa .
Steve314

Câu trả lời:


10

Vấn đề không phải là tên, mà là bạn đang đặt quá nhiều vào một lớp.

Trong lớp ví dụ của bạn, một số phần rất cụ thể (làm thế nào các thư sẽ được lấy). Các phần khác rất trừu tượng (những gì bạn sẽ làm với các thư).

Tốt hơn để làm điều này với các lớp riêng biệt, hơn là với thừa kế.

Tôi đề nghị:

  • Trình thông báo trừu tượng, được phân lớp bởi POPMailBoxDoader

  • một lớp khác sở hữu một POPMailBoxDoader và thực hiện một cái gì đó với các tin nhắn.


Điều này nghe có vẻ chính xác. Nghe có vẻ như nếu bạn thấy mình đặt tên một cái gì đó là "processEvent" hoặc một lớp "MessageProcessor", có một cơ hội tốt mà bạn có thể đã thiết kế trên bố cục thay vì dẫn xuất. Trong trường hợp này, đó là một sự đánh đổi, vì người bảo trì tính linh hoạt có thể hữu ích nhưng khách hàng sẽ khó chịu khi tự hỏi chính xác mỗi chức năng làm gì (so với người bảo trì).
djechlin

6

Nếu tôi không thể tìm thấy một tên hay cho một lớp, tôi viết một tài liệu mã nội tuyến cho lớp đó. Nó mô tả mục đích của lớp học trong một mùi hương. Thông thường tôi có thể lấy được một tên hay cho lớp từ mô tả này. Điều này cũng hữu ích cho các lớp trừu tượng.

Nếu mô tả của lớp là "Đăng nhập vào hộp thư đến của người dùng và xử lý các thông báo từ nó", tôi sẽ đề xuất "InboxProcessor" làm tên lớp. Nếu một lớp phái sinh có "Đăng nhập vào hộp thư đến của người dùng và chuyển email spam vào thư mục thư rác" làm mô tả, tôi sẽ chọn "InboxSpamMover" làm tên.

Tôi không thấy vấn đề gì khi sử dụng các tên chung như "bộ xử lý" nếu nó phản ánh mục đích chung của một lớp trừu tượng.

Nếu bạn gặp vấn đề với việc mô tả mục đích của một lớp trong một hoặc hai mùi hương, thì bạn có thể gặp vấn đề về thiết kế. Có thể lớp học đang làm quá nhiều và vi phạm Nguyên tắc Trách nhiệm duy nhất . Điều này cũng áp dụng cho các lớp trừu tượng.


2

Để diễn giải Frank Zappa, đó là những gì nó nên và được đặt tên theo cách đó. Ví dụ của bạn không đào sâu đủ về loại xử lý đang diễn ra. Nó là một EmailToTroubleTicketProcessor, một EmailGrammarCorrectorhay một EmailSpamDetector?

Vấn đề rõ ràng hơn đối với các phương pháp trừu tượng, trong đó bạn thực sự không thể trả lời câu hỏi "cái này làm gì?" bởi vì câu trả lời chỉ đơn giản là "bất cứ điều gì khách hàng muốn."

Điều đó không chính xác; câu hỏi bạn không thể trả lời cho một cái gì đó trừu tượng là " làm thế nào để nó làm gì?" bởi vì đó là đặc thù Nếu một EmailSenderlớp có một DeliveryStatus deliver(Email e)phương thức, có một hợp đồng ngụ ý rằng việc triển khai sẽ nhận email, cố gắng gửi nó và trả lại một số trạng thái về cách nó đã đi. Bạn không quan tâm liệu nó có kết nối với máy chủ SMTP hay in ra để được gắn vào một con chim bồ câu đang nở miễn là việc thực hiện đúng như những gì đã hứa. Tóm tắt chỉ định lượng lời hứa đó để một triển khai có thể nói, "ừ, tôi làm điều đó."


Thế còn khi hàm kết thúc ở một thiết bị đầu cuối nào đó, thì lớp trừu tượng đang nói "và cái này ở đây, làm bất cứ điều gì bạn muốn với nó?" ví dụ: phương thức không có quyền truy cập vào trạng thái, loại trả về void, không ném.
djechlin

Đó vẫn là điều tương tự. Ngay cả khi phương thức của bạn là void doWhatYouDoWith(Email e), bạn vẫn có thể gọi lớp là một EmailDisposer, đủ cụ thể để nói những gì nó làm nhưng đủ chung chung để làm thế nào là tùy thuộc vào việc thực hiện. Mặc dù tôi nghĩ @KrisVanBael đóng đinh nó: nếu bạn đã dùng đến một thứ gì đó mơ hồ, có thể có quá nhiều dưới một mái nhà.
Blrfl

0

Hãy suy nghĩ về lý do tại sao nó xấu khi sử dụng những từ như vậy. Họ có mô tả? Những từ nào có để mô tả các lớp học? EmailBaseClass? Điều đó có thể được mô tả nhiều hơn nói EmailManager hoặc một cái gì đó tương tự? Điều quan trọng là có một cái nhìn sâu sắc về lớp trong câu hỏi, vì vậy hãy tìm động từ hoặc danh từ thích hợp. Hãy đối xử với mã của bạn như nó là thơ.


"EmailBaseClass" sẽ giống như đặt tên int age"ageInteger", thậm chí còn tệ hơn vì tôi dự kiến ​​sẽ lấy được email văn bản đơn giản, email MIME, v.v. Không cần mô tả những gì đứng trước từ abstractở vị trí đầu tiên (đây là Java). Bạn có cái nhìn sâu sắc cụ thể nào cho phần cơ sở của lớp này không? Và cái nhìn sâu sắc hơn vẫn không giải quyết được vấn đề đặt tên một thứ gì đó sẽ vượt qua một mối quan hệ là - tôi có thể có một cái gì đó quá mơ hồ hoặc quá chung chung, tôi không thấy cách nào khác trừ khi tôi có cái nhìn sâu sắc hơn để có cái nhìn sâu sắc hơn.
djechlin

@djechlin - có những trường hợp hiếm hoi trong đó ageIntegerhoặc một cái gì đó giống như nó thực sự phù hợp. Ký hiệu Hungary là một phiên bản rút gọn từ bối cảnh nó đã xảy ra rất nhiều. Chắc chắn, có những lúc bạn có thể cần một cái gì đó dọc theo dòng ageNumericageStringtrong cùng một phạm vi, với một dấu hiệu của loại trong tên là cách dễ nhất và rõ ràng nhất để phân tán.
Steve314

@djechlin Cá nhân tôi thấy dễ dàng nhất khi làm việc với mã mà tôi chỉ có thể nhìn vào để hiểu. Đó là, tên cho tôi biết những gì tôi đang làm việc với. Không cần biết systemControllerlà một lớp cơ sở trừu tượng hay một chiếc lá trong một hệ thống phân cấp lớn. Tất nhiên điều này có thể được khắc phục bằng IDE (như tôi đoán là trường hợp của hầu hết sự phát triển Java?) Có thể thông báo ngay lập tức cho người dùng về nội dung và cấu trúc của lớp để những cái tên sâu sắc thực sự không thể được chứng minh trong tĩnh mạch tương tự.
zxcdw
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.