Làm thế nào và tại sao để quyết định giữa các phương thức đặt tên với các loại tiền tố và nhận được


48

Tôi luôn gặp khó khăn trong việc tìm ra nếu tôi nên đặt tên cho một phương thức nhất định bắt đầu bằng getSomethingso với findSomething.

Vấn đề nằm ở việc tạo các trình trợ giúp cho các API được thiết kế kém. Điều này thường xảy ra khi lấy dữ liệu từ một đối tượng, đòi hỏi đối tượng làm tham số. Đây là một ví dụ đơn giản:

public String getRevision(Item item) {
    service.load(item, "revision");
    // there is usually more work to do before getting the data..
    try {
        return item.get_revision();
    }
    catch(NotLoadedException exception) {
        log.error("Property named 'property_name' was not loaded", exception);
    }
    return null;
}

Làm thế nào và tại sao để quyết định giữa việc đặt tên phương thức này là getRevision()hay findRevision()?


2
người trợ giúp tốt nhất cho API được thiết kế kém không gây rắc rối với việc đặt tên khó khăn mà thiết lập Lớp chống tham nhũng : "Nếu ứng dụng của bạn cần xử lý cơ sở dữ liệu hoặc ứng dụng khác có mô hình không mong muốn hoặc không thể áp dụng cho mô hình bạn muốn trong ứng dụng của mình, sử dụng AnticorruptionLayer để dịch sang / từ mô hình đó và của bạn. "
gnat

1
Tôi chưa bao giờ nghe về khái niệm này trước đây. Bạn có bất kỳ liên kết tốt hơn với các ví dụ?
knowasilya

1
Tìm kiếm trên web, có khá nhiều thông tin về nó. Ví dụ: Cấu trúc của một lớp, chống tham nhũng, Phần 1 "có khả năng là ... bạn đang không tránh khỏi phải đối mặt với nhiệm vụ tương tác với spaghetti đó là đã có Nhập lớp, chống tham nhũng ...."
một loại muôi

Câu trả lời:


83

Tôi sử dụng Getkhi tôi biết thời gian truy xuất sẽ rất ngắn (như trong tra cứu từ bảng băm hoặc btree).

Findngụ ý một quá trình tìm kiếm hoặc thuật toán tính toán đòi hỏi một khoảng thời gian "dài hơn" để thực thi (đối với một số giá trị tùy ý dài hơn).


3
+1 Tôi sử dụng get khi lấy và tìm khi nào công việc phải hoàn thành để thực hiện get.
Jim

5
Nếu tính đến việc thay đổi mã (một số phần được tối ưu hóa và thay đổi thuật toán) và thay đổi API thường không thể, nó không giống như một tiêu chí đúng. Bạn sẽ làm gì nếu thay thế findbằng thuật toán bảng băm sau này?
meze

2
Tôi cũng cho rằng, khi đọc một cuộc gọi, "tìm" có thể được gọi khi tìm thấy không thành công vì tiêu chí tìm kiếm không thành công, trong khi "nhận" được dự kiến ​​sẽ thành công trừ khi có một số vấn đề bất thường.
gnasher729

Điều gì xảy ra nếu hàm chấp nhận một tham số tùy chọn để lọc kết quả dựa trên một số điều kiện? Cả hai getfindsẽ áp dụng tùy thuộc vào cách sử dụng.
ESR

62

Tôi sẽ nói rằng findcó thể thất bại nhưng getkhông nên.


25
Nếu bạn có nghĩa là findcó thể trả lại NULL trong khi getsẽ không bao giờ trả lại NULL nhưng có thể ném (hoặc khẳng định), tôi đồng ý.
Sjoerd

1
Tôi hoàn toàn đồng ý với @Sjoerd về điều này.
mh

Và nếu find()trả lại Optional<>thì sao? Trong trường hợp đó findcũng nullan toàn.
TheCoder

42

Để trích dẫn một cuộc trò chuyện tôi thường có với các con tôi:

tôi: Này nhóc! Đi tìm tôi vài cục pin

Đứa trẻ: Nhưng họ ở đâu?

tôi: đó là lý do tại sao tôi bảo bạn đi tìm chúng Nếu tôi biết họ ở đâu, tôi sẽ bảo bạn đi lấy chúng. Hoặc bạn có thể hỏi mẹ của bạn.

Ý tưởng tương tự giữ:

  • sử dụng "get" cho một phương thức trả về một phần thông tin có sẵn với giá rẻ (và có thể được nội tuyến hoặc tối ưu hóa đi) hoặc cho một phần thông tin thuộc sở hữu duy nhất của đối tượng này.

  • sử dụng "find" cho một phương thức hoạt động để lấy một phần thông tin hoặc sử dụng các đối tượng khác để tìm nó.


16
Chỉ có một lập trình viên sẽ có cuộc trò chuyện này với con của họ. "Bạn có muốn bỏ rác không?" "Không." "Bạn sẽ lấy rác ra chứ?" "Đúng."
Robert Harvey

@RobertHarvey Tôi nghĩ rằng tôi đang gặp vấn đề này với mọi người. Bất cứ khi nào ai đó cố gắng giải thích một cái gì đó, hoặc đặt câu hỏi, tôi thường đặt câu hỏi lại và nói với họ để được rõ ràng về nó. Nếu không, chúng tôi thường kết thúc với một vấn đề XY. Nếu tôi không làm điều đó, tôi cảm thấy giống như một tính năng tự động hoàn thành đi bộ. Bạn không biết những gì trong tâm trí của bạn, bạn không thể nói nó thành lời, bạn lảm nhảm vài từ và mong tôi làm tất cả "suy nghĩ" cho bạn và giúp bạn điều đó? Không, không xảy ra :)
akinuri

3

Tìm ngụ ý không có kết quả, như khi thực hiện truy vấn cơ sở dữ liệu với một số tham số có thể thay đổi giữa các cuộc gọi. Mặt khác, có nghĩa là các kết quả được biết đến theo phương pháp trước hoặc sẽ không thay đổi một khi đã biết, rằng không có tham số nào cho cuộc gọi.
Vì vậy, tôi sẽ sử dụng ví dụ Khách hàng findCustomerById (khách hàng dài) và Khách hàng getCustomer ()


3

Tôi áp dụng mô hình sau:

  • Foo GetFoo() không thể trả về null và độ phức tạp của nó là O (log (n)) hoặc ít hơn
  • bool TryGetFoo(out Foo) có thể trả về null và độ phức tạp của nó là O (log (n)) hoặc ít hơn
  • Foo FindFoo() không thể trả về null và độ phức tạp của nó nhiều hơn O (log (n))
  • bool TryFindFoo(out Foo) có thể trả về null và độ phức tạp của nó nhiều hơn O (log (n))

Bằng cách đó, mã khá rõ ràng về ý định và sự phức tạp mà bạn có thể mong đợi.

Thông thường, Getters dành cho danh sách trực tiếp hoặc truy cập từ điển / bộ.
Công cụ tìm kiếm được tìm kiếm sâu, quét toàn bộ danh sách, v.v ...

Trong trường hợp của bạn:

public bool TryGetRevision( Item item, out String revision ) 
{
    service.load( item, "revision" );
    // there is usually more work to do before getting the data..
    try 
    {
        revision = item.get_revision();
        return true;
    }
    catch( NotLoadedException exception )
    {
        log.error( "Property named 'property_name' was not loaded", exception );
        revision = "";
        return false;
    }
}

+1 cho try, ngắn gọn và chính xác
SpaceTrucker

2

getlà phù hợp trong mọi trường hợp _ trong thực tế, người ta thường cho rằng để có được thứ gì đó bạn cần tìm thứ đó trước. Vì vậy, nếu bạn không chắc chắn, hãy sử dụng get.

Tôi sẽ sử dụng findcho các phương thức như findMinimum()hoặc findOptimal(), ví dụ, nơi có một số thuật toán đặc biệt tính toán giá trị trả về và không chỉ đơn giản là yêu cầu DB, hệ thống tệp, máy chủ từ xa, v.v. để nhận một số dữ liệu.


1
Điểm tốt. Cá nhân tôi có thể không sử dụng findlàm tiền tố trong các ví dụ bạn cung cấp. Đối với các tác vụ tính toán, như các tác vụ trong ví dụ của bạn, tôi sẽ sử dụng calculatehoặc compute.
biết đến


1

Tôi thường sẽ sử dụng Getđể truy xuất một đối tượng / giá trị và Findđể lấy vị trí của nó (ví dụ trong một mảng).

ví dụ:

object o = obj.GetItem( 'name');

integer i = somearray.Find( 'name');

0

Đối với tôi, findngụ ý có thể có nhiều hơn một kết quả hiện tại. getchỉ ngụ ý một.


8
Có vẻ như nó có cảm giác đó, nhưng tôi không chắc là mình hoàn toàn đồng ý. Hãy suy nghĩ về nó theo cách này: getCatvs findCatvs getCatsvs findCats. Các find..vẫn còn đại diện cho các đối tượng số ít được trả lại. Theo tôi, số nhiều nên được thêm vào danh từ.
knowasilya
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.