Đây có phải là mùi mã nếu một phương thức riêng gọi một phương thức công khai?


25

Đây có phải là mùi mã để gọi phương thức công khai trong phương thức riêng của cùng một đối tượng không?


AAMOI bạn có một ví dụ cụ thể không?
ocodo

Không, không phải hiện tại. Chỉ cần nhớ một trường hợp mà tôi đã thảo luận với các đồng nghiệp của tôi. Muốn có được một số ý kiến ​​ở đây là tốt.
Eimantas

5
Thông thường tôi có thể tìm ra một từ viết tắt theo ngữ cảnh, nhưng AAMOI tôi chắc chắn phải tìm kiếm
Carson Myers

@Carson - bạn đã tìm thấy gì chưa?
Eimantas

4
Như một vấn đề thú vị
Carson Myers

Câu trả lời:


33

Không có mùi không tệ. Điều này có thể cần thiết, tại sao bạn nghi ngờ nó sai? Một phương thức ở cấp độ nguyên tử là một thực thể độc lập thực hiện một nhiệm vụ. Miễn là nó thực hiện một nhiệm vụ bất cứ ai có quyền truy cập vào nó đều có thể gọi nó để hoàn thành nhiệm vụ.


Tôi đồng ý. Một số phương pháp cung cấp chức năng hữu ích cho cả bên trong và cho người gọi bên ngoài. Cờ đỏ có thể là nếu phương thức công khai rất cụ thể đối với việc triển khai nội bộ, nhưng ngay cả khi đó, không phải mọi lớp đều có ý định che giấu nội bộ của nó. Ví dụ, tôi thường có lớp "công cụ" cấu trúc dữ liệu bên dưới lớp loại trừu tượng chứa - theo cách đó tôi có thể sử dụng lại một số mã cấu trúc dữ liệu cho các cấu trúc dữ liệu khác bên dưới các thùng chứa khác.
Steve314

20

Mùi mã? Vâng, không phải là một thực sự xấu, nhưng một chỉ số tốt rằng lớp có thể có quá nhiều trách nhiệm.

Hãy coi đó là một dấu hiệu cho thấy lớp có thể cần được chia thành các đối tượng khác nhau, các phương thức riêng không thực sự cần phải gọi các phương thức công khai của cùng một đối tượng, chắc chắn trong một thiết kế OO sạch.

Tất nhiên, một khi bạn đã kiểm tra lớp và lý do của lệnh gọi phương thức là rõ ràng, thì đó có thể là một cách sử dụng hoàn toàn hợp lý, nói chung, bạn mong đợi các phương thức tiện ích cho lớp là riêng tư, nhưng nếu một phương thức đủ hữu ích để công khai và được sử dụng bởi các phương pháp khác, nói chung, tôi mong muốn các phương thức đó cũng được công khai.

Như với tất cả các mã có mùi, đây là một động lực để kiểm tra mã hơn nữa, hợp lý hóa và có thể tái cấu trúc, nhưng không phải là một nguyên nhân để báo động.


5
+1 cho 'không phải là nguyên nhân để báo động'. Quá nhiều lần chúng ta thấy một "mùi" và ngay lập tức chuyển sang chế độ tái cấu trúc mà không cần suy nghĩ.
Michael K

+1 cho SRP. Tôi vừa gặp phải trường hợp một người trang trí không làm việc vì lớp trang trí đang gọi chức năng công khai của chính nó, bỏ qua người trang trí. Giải pháp: chia lớp thành hai và tiêm phụ thuộc trang trí.
Jon Hulka

18

Nó có thể dẫn đến những bất ngờ khó chịu nếu ai đó chưa đọc mã nguồn của lớp này cố gắng phân lớp nó và ghi đè phương thức công khai. Cho dù đó là một mối quan tâm thực sự rõ ràng phụ thuộc vào tình huống của bạn. Có lẽ bạn nên xem xét việc thực hiện phương pháp công khai hoặc thậm chí là lớp cuối cùng.


Tại sao? Nếu một phương thức công khai được ghi đè dẫn đến những bất ngờ khó chịu, liệu có thực sự quan trọng ai gọi phương thức đó không?
dùng281377

4
Có nó làm. Nếu ghi đè một phương thức công khai phá vỡ một phương thức công khai khác, tôi cũng có thể ghi đè phương thức khác đó. Nếu nó phá vỡ một phương thức riêng tư, tôi có thể ....?
Kim

5
Một bất ngờ khó chịu do việc ghi đè một phương thức công khai là bản thân mùi mã. Một mùi hôi thối, thực sự.
Larry Coleman

Kim: nếu phương thức này là công khai, bạn phải giả sử rằng các lớp khác cũng gọi phương thức đó ...
user281377

@Larry: Chính xác! Một phương thức riêng tư (thường chứa các giả định dành riêng cho việc thực hiện) gọi một phương thức công khai làm cho nhiều khả năng việc ghi đè phương thức công khai sẽ phá vỡ mọi thứ.
Kim

5

Tôi không nghĩ rằng chúng ta có thể genaralize.

Tất cả phụ thuộc rất nhiều vào bối cảnh.

Tôi có thể có một phương thức tiện ích công cộng trong một lớp được các lớp khác sử dụng và một số phương thức riêng tư trong cùng một lớp.


5

Không. Những gì khác nên được thực hiện trong trường hợp đó? Làm cho phương thức riêng tư công khai hay phương thức công khai riêng tư? Sao chép-Dán mã từ phương thức công khai sang phương thức riêng tư?


Hoặc có phương thức công khai ủy quyền cho một phương thức riêng (mới) được gọi bằng phương thức riêng khác. Nhưng, tại sao phải bận tâm?
Lawrence Dol

4

KHÔNG , không có mùi hôi ở đây.

Nếu chúng ta thực hiện giao diện của một hàng đợi với Danh sách, có phải là mùi khó chịu khi chỉ gọi các chức năng Danh sách thích hợp để đạt được việc thực hiện hàng đợi một cách dễ dàng?

nếu bạn có một cái gì đó và bạn muốn chuyển đổi nó thành một thứ khác (như trình bao bọc) thì nó không phải là mùi khó chịu, mã của nó có thể sử dụng lại với mẫu thiết kế được thực hiện ở cấp độ chức năng (là một chức năng một đối tượng?)


2

Tôi biết đây là một bài viết cũ, nhưng đó là điều mà tôi đã tranh luận trong công việc. Tôi 'coi' đây là mùi mã và không thể hiểu tại sao bạn lại muốn làm điều này. Nếu một phương thức riêng phải gọi một phương thức công khai, thì nội dung của phương thức chung sẽ được lấy và đặt trong một phương thức riêng, mà cả hai phương thức đều có thể gọi. Tại sao?

  1. Phương thức công khai có thể chứa các kiểm tra không cần thiết sau khi mã thực thi của bạn bên trong. Nó có thể nhận được UserObj và muốn kiểm tra quyền của người dùng chẳng hạn.

  2. Sau cuộc gọi công khai, bạn có thể có yêu cầu khóa đối tượng, nếu bạn đang sử dụng luồng, vì vậy, bên trong, bạn sẽ không muốn gọi lại cho phương thức công khai.

  3. Theo tôi, nhiều khả năng giới thiệu các lỗi tròn và các vòng lặp vô hạn và theo các ngoại lệ mem theo ý kiến ​​của tôi.

  4. Đơn giản và đơn giản, thiết kế xấu và "lười biếng". Phương pháp công cộng cung cấp quyền truy cập vào thế giới bên ngoài. Không có lý do để quay trở lại bên ngoài khi bạn đã ở trong.


1
Điều gì xảy ra nếu phương thức công khai hiện có được gọi bởi nhiều lớp khác? Làm cho nó riêng tư sẽ phá vỡ điều đó. Hãy nhớ rằng các phương thức công khai được gọi bởi các lớp khác vì các lý do khác, không chỉ lớp này. kinda tại sao phương pháp công cộng tồn tại.
Michael Durrant

Tôi đã nói rằng 'nội dung của phương thức công khai nên được thực hiện và được đặt trong một phương thức riêng tư ...' Phương thức công khai sẽ vẫn còn, nhưng thực hiện cuộc gọi đến phương thức riêng tư mới. Như bất kỳ phương pháp riêng tư nào khác cần sử dụng lại chức năng tương tự.
Mark Graham

Vì vậy, bạn đang thêm một phương thức khác không vì lý do nào khác ngoài - tốt, bởi vì bạn đã tuyên bố đây là "mùi mã". Phương pháp vô nghĩa là một mùi mã tồi tệ hơn.
gnasher729

Xin lỗi, nhưng, tôi không chỉ liệt kê một số lý do ở trên. Rất nhiều mã tôi viết là dành cho các hệ thống kinh doanh, nhiều lớp được giới hạn cho người dùng dựa trên vai trò. Nhiều phương thức công khai kiểm tra quyền và thông số người dùng. Tại sao tôi muốn gọi lại cho cùng một phương thức công khai để sử dụng lại chức năng của nó và kiểm tra lại quyền của người dùng?
Mark Graham

Trong đời tôi chưa bao giờ cần phải gọi một phương thức công khai từ một phương thức riêng tư. Nó chỉ có vẻ và cảm thấy rất sai với tôi. Tôi thực sự ngạc nhiên khi hầu hết mọi người nghĩ rằng nó ổn.
Bẫy

2

Hãy tưởng tượng ngược lại. Bạn đang ở trong một phương thức riêng tư và bạn cần chức năng trong một phương thức công khai Điều gì xảy ra nếu bạn không thể gọi phương thức công khai đó từ phương thức riêng tư. Bạn sẽ làm gì?

  • Tạo một phương thức riêng tư trùng lặp? Không
  • Tạo một phương pháp công cộng đặc biệt cho sự xuất hiện? Không
  • Gọi một phương thức riêng đặc biệt có thể gọi phương thức công khai? Không
  • Một số loại siêu có thể làm điều này? Không

Câu trả lời rõ ràng là khi bạn muốn chức năng trong một phương thức công khai, bạn sẽ có thể gọi phương thức đó từ các phương thức của lớp này hoặc từ các lớp khác.


1

Trong mã của tôi, tôi thường tạo ra các trình tải tải lười biếng, nghĩa là đối tượng được khởi tạo lần đầu tiên khi nó được yêu cầu và sau đó sử dụng lại cùng một đối tượng được khởi tạo. Tuy nhiên, một đối tượng được khởi tạo bằng cách sử dụng tải lười biếng ngụ ý rằng nó có thể không nhất thiết phải được khởi tạo tại bất kỳ điểm nào. Thay vì quấn đầu xung quanh chuỗi các cuộc gọi để tôi biết rằng đối tượng đó đã được khởi tạo hoặc lặp lại cùng một mã của một tải lười biếng bên trong một phương thức khác, tôi chỉ cần gọi trình tải lười biếng bất cứ khi nào tôi cần đối tượng đó.

Giống như bạn có thể sử dụng các phương thức công khai một cách thông minh, bạn cũng có thể sử dụng chúng không chính xác. Một ví dụ về điều này có thể là một phương thức công khai xử lý các tham số của nó trước khi gọi một phương thức riêng tư khác. Sẽ là một sai lầm nếu gọi phương thức công khai đó một cách tình cờ đơn giản chỉ vì bạn có cùng tham số. Lỗi là tinh tế nhưng đó là lỗi thiết kế hơn bất kỳ điều gì khác và yêu cầu bạn học cách quản lý với các tham số của phương thức bên trong hơn là các tham số của phương thức chung.

Vì vậy, để trả lời câu hỏi của bạn, chắc chắn đó không phải là mã xấu nếu bạn sử dụng đúng.


1

Câu hỏi bạn cần tự hỏi mình là tại sao lớp học của bạn có cùng nhu cầu với khách hàng của lớp bạn? Thông thường một lớp có nhu cầu rất khác nhau từ khách hàng của nó. Vì vậy, có, đây là một dấu hiệu cho thấy bạn có một trong hai

(a) phơi bày một cái gì đó công khai mà nên riêng tư; hoặc là

(b) hành vi của lớp không đủ hẹp (nghĩ nguyên tắc trách nhiệm duy nhất).

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.