2008-09-17 28 views
10

getEmployeeNameByBatchId (int Id lô)
getEmployeeNameBySSN (Object SSN)
getEmployeeNameByEmailId (String EmailId)
getEmployeeNameBySalaryAccount (SalaryAccount salaryAccount)
Nhận Phương pháp: Một vs Nhiều

hoặc

getEmployeeName (int typeOfIdentifier, byte [] identifier) ​​-> Trong phương thức này, typeOfIdentifier cho biết nếu định danh là batchID/SSN/emailID/salaryAccount

Điều nào ở trên là cách tốt hơn để thực hiện phương thức get?

Các phương pháp này sẽ có trong Servlet và các cuộc gọi sẽ được thực hiện từ API sẽ được cung cấp cho khách hàng.

+0

Hãy để các trận chiến tôn giáo ... BEGIN !!! – CodeChimp

Trả lời

9

Tại sao không quá tải phương thức getEmployeeName (??)?

getEmployeeName (int Id lô)
getEmployeeName (object SSN) (ý tưởng tồi)
getEmployeeName (String Email)
, vv

Có vẻ một cách tiếp cận tốt 'nhiều' với tôi.

+0

Có thể không phải lúc nào cũng linh hoạt nếu có nhiều trường cùng loại dữ liệu. getEmployeeName (chuỗi email) getEmployeeName (chuỗi passportNumber) getEmployeeName (chuỗi telephoneNumber) .... – icelava

+0

Nhiều. Dễ đọc hơn. Nếu bạn cần tất cả các biến thể này, hãy viết tất cả chúng. – Gishu

+0

Đó không phải là cách tiếp cận tốt vì bạn không thể có tiêu chí với cùng loại. – jrudolph

3

Tôi muốn sử dụng phương pháp "nhiều". Nó có vẻ trực quan hơn với tôi và ít bị lỗi hơn.

+1

Ít bị lỗi, nhưng có lẽ dễ bị trùng lặp mã hơn. – jrudolph

0

Tôi sẽ sử dụng tùy chọn đầu tiên hoặc quá tải trong trường hợp này, khi bạn có 4 chữ ký tham số khác nhau. Tuy nhiên, được cụ thể giúp với sự hiểu biết mã 3 tháng kể từ bây giờ.

1

Tùy chọn đầu tiên, không có câu hỏi. Hãy rõ ràng. Nó sẽ hỗ trợ rất nhiều trong bảo trì và thực sự không có nhược điểm.

+0

Bạn có thể sẽ có 4 phương pháp gần như tương tự. Đó là nhiều hơn để duy trì không ít ... – jrudolph

+0

Định nghĩa về khả năng bảo trì của bạn không giống như của tôi. –

0

Đầu tiên có lẽ là tốt nhất trong Java, xem xét nó là typesafe (không giống như khác). Ngoài ra, đối với các loại "bình thường", giải pháp thứ hai dường như chỉ cung cấp mức sử dụng cồng kềnh cho người dùng. Tuy nhiên, vì bạn đang sử dụng Object làm kiểu cho SSN (có nghĩa ngữ nghĩa ngoài Object), có thể bạn sẽ không loại bỏ được loại API đó.

Tất cả trong tất cả, trong trường hợp cụ thể này, tôi đã sử dụng phương pháp này với nhiều getters. Nếu tất cả các số nhận dạng có loại lớp của riêng chúng, tôi có thể đã đi tuyến thứ hai, nhưng chuyển đổi nội bộ trên lớp thay vì một mã định danh kiểu do ứng dụng cung cấp.

0

Liệu logic bên trong mỗi phương pháp đó có giống nhau không?

Nếu vậy, phương pháp đơn với thông số nhận dạng có thể có ý nghĩa hơn (đơn giản và giảm mã lặp lại).

Nếu logic/thủ tục khác nhau rất nhiều giữa các loại, một phương pháp cho mỗi loại có thể được ưu tiên.

1

@Stephan: rất khó để quá tải một trường hợp như thế này (nói chung) vì các loại thông số có thể không phân biệt đối xử, ví dụ:,

  • getEmployeeNameByBatchId (int Id lô)
  • getEmployeeNameByRoomNumber (int roomNumber)

Xem thêm hai phương pháp getEmployeeNameBySSN, getEmployeeNameByEmailId trong việc niêm yết ban đầu.

0

Khi những người khác đề xuất tùy chọn đầu tiên có vẻ là tùy chọn tốt nhất. Điều thứ hai có thể có ý nghĩa khi bạn viết mã, nhưng khi một người nào đó khác đi cùng về sau, khó có thể tìm ra cách sử dụng mã. (Tôi biết, bạn có ý kiến ​​và bạn luôn có thể đào sâu vào mã, nhưng GetemployeeNameById tự giải thích thêm)

Lưu ý: Btw, việc sử dụng Enums có thể cần xem xét trong một số trường hợp.

-2

Bạn đang suy nghĩ C/C++.

Sử dụng các đối tượng thay vì byte nhận dạng (hoặc int).

Bad của tôi, cách tiếp cận quá tải là tốt hơn và sử dụng SSN như một khóa chính không phải là quá tốt

public ??? getEmployeeName(Object obj){ 

if (obj instanceof Integer){ 

    ... 

} else if (obj instanceof String){ 

... 

} else if .... // and so on 


} else throw SomeMeaningFullRuntimeException() 

return employeeName 
} 

Tôi nghĩ rằng đó là tốt hơn để sử dụng ngoại lệ không được kiểm soát để phát tín hiệu đầu vào không chính xác.

Viết tài liệu để khách hàng biết những gì các đối tượng mong đợi. Hoặc tạo trình bao bọc của riêng bạn. Tôi thích tùy chọn đầu tiên.

+0

Tại sao dựa vào ngoại lệ thời gian chạy khi bạn có thể có độ an toàn thời gian biên dịch tĩnh? – jrudolph

+0

Tôi đồng ý với jrudolph. Điều bạn đang viết mã là "lập trình chuyển mạch C" thuần khiết. Mặc dù nó tốt hơn mảng byte, nhưng đây không phải là giải pháp tốt. – paercebal

0

Trong trường hợp tầm thường như thế này, tôi sẽ bị quá tải. Đó là:

getEmployeeName(int batchID); 
getEmployeeName(Object SSN); 

etc. 

Chỉ trong trường hợp đặc biệt tôi sẽ xác định loại đối số trong tên phương pháp, tức là nếu các loại lập luận rất khó để xác định, nếu có một số loại tranh luận tha có cùng kiểu dữ liệu (batchId và employeeId, cả hai int), hoặc nếu các phương thức lấy ra nhân viên là hoàn toàn khác nhau đối với từng loại đối số.

Tôi không thể hiểu tại sao mà tôi đã từng sử dụng này

getEmployeeName(int typeOfIdentifier, byte[] identifier) 

vì nó đòi hỏi cả hai callee và gọi để đúc các giá trị dựa trên typeOfIdentifier. Thiết kế xấu.

0

Nếu bạn viết lại câu hỏi mà bạn có thể kết thúc hỏi:

"SELECT tên TỪ ..."
"SELECT SSN TỪ ..."
"SELECT email TỪ ..."
vs .
"CHỌN * TỪ ..."

Và tôi đoán câu trả lời cho điều này thật dễ dàng và mọi người đều biết điều đó.

Điều gì sẽ xảy ra nếu bạn thay đổi lớp Nhân viên? Ví dụ: Bạn phải xóa email và thêm bộ lọc mới như bộ phận. Với giải pháp thứ hai, bạn có một nguy cơ rất lớn không nhận thấy bất kỳ lỗi nào nếu bạn chỉ thay đổi thứ tự của số nhận dạng int "hằng số". Với giải pháp đầu tiên, bạn sẽ luôn luôn thông báo nếu bạn đang sử dụng phương pháp trong một số lớp học bị lãng quên dài, nếu không bạn sẽ quên sửa đổi để định danh mới.

2

Các phương pháp là ví dụ hoàn hảo cho việc sử dụng quá tải.

getEmployeeName(int batchID) 
getEmployeeName(Object SSN) 
getEmployeeName(String emailID) 
getEmployeeName(SalaryAccount salaryAccount) 

Nếu các phương pháp chế biến có chung bên trong, chỉ cần viết thêm một getEmplyeeNameImpl (...) và trích xuất có mã chung để tránh trùng lặp

+0

Nhưng dòng "getEmployeeName (Object SSN)" đi xa ... Kiểu "Object" sẽ làm cho hầu như bất kỳ quá tải nào khác vô nghĩa (rất giống với sự sợ hãi void * từ C. – paercebal

3

tôi không thích getXByY() - đó có thể là mát mẻ trong PHP, nhưng tôi không thích nó trong Java (ymmv).

Tôi muốn đi quá tải, trừ khi bạn có thuộc tính của cùng một kiểu dữ liệu. Trong trường hợp đó, tôi sẽ làm một cái gì đó tương tự như lựa chọn thứ hai của bạn, nhưng thay vì sử dụng ints, tôi sẽ sử dụng một Enum cho loại an toàn và rõ ràng. Và thay vì byte [], tôi muốn sử dụng Object (vì autoboxing, điều này cũng làm việc cho primitives).

0

Cá nhân tôi thích đặt tên rõ ràng "... ByRoomNumber" vì nếu bạn kết thúc với nhiều "quá tải", cuối cùng bạn sẽ đưa ra các lỗi không mong muốn. Rõ ràng là imho cách tốt nhất.

7

Bạn có thể sử dụng một cái gì đó như thế:

interface Employee{ 
    public String getName(); 
    int getBatchId(); 
} 
interface Filter{ 
    boolean matches(Employee e); 
} 
public Filter byName(final String name){ 
    return new Filter(){ 
     public boolean matches(Employee e) { 
      return e.getName().equals(name); 
     } 
    }; 
} 
public Filter byBatchId(final int id){ 
    return new Filter(){ 
     public boolean matches(Employee e) { 
      return e.getBatchId() == id; 
     } 
    }; 
} 
public Employee findEmployee(Filter sel){ 
    List<Employee> allEmployees = null; 
    for (Employee e:allEmployees) 
     if (sel.matches(e)) 
      return e; 
    return null; 
} 
public void usage(){ 
    findEmployee(byName("Gustav")); 
    findEmployee(byBatchId(5)); 
} 

Nếu bạn làm các việc lọc bởi một truy vấn SQL bạn sẽ sử dụng giao diện Filter để soạn một mệnh đề WHERE.

Những điều tốt với phương pháp này là bạn có thể kết hợp hai bộ lọc một cách dễ dàng với:

public Filter and(final Filter f1,final Filter f2){ 
    return new Filter(){ 
     public boolean matches(Employee e) { 
      return f1.matches(e) && f2.matches(e); 
     } 
    }; 
} 

và sử dụng nó như thế:

findEmployee(and(byName("Gustav"),byBatchId(5))); 

Những gì bạn nhận được là tương tự như Criteria API trong Hibernate.

+0

Đây là một cách tiếp cận tuyệt vời (cá nhân tôi sẽ sử dụng và đã sử dụng nó) nhưng với một ngoại lệ.Thực sự xem xét trước cho dù bạn cần tất cả những gì thêm mã làm một cái gì đó rất đơn giản.Đôi khi đơn giản là tốt hơn .. – Josh

+0

Âm thanh như DSL với tôi – rpattabi

+0

Overkill Câu hỏi là về accessors. Một số người cho rằng điều này đã quá nhiều chi phí (và họ sẽ sai) Những gì bạn đề xuất là một bộ khung đầy đủ ... Người dùng chỉ muốn tên nhân viên ... :-) – paercebal

1

Thỉnh thoảng có thể triệu tập nhiều hơn để sử dụng số specification pattern.

Ví dụ: GetEmployee (ISpecification < nhân viên > đặc điểm kỹ thuật)

Và sau đó bắt đầu xác định thông số kỹ thuật của bạn ...

NameSpecification: ISpecification < nhân viên >
{
tên chuỗi tư nhân;
tên công khaiSpecification (tên chuỗi) {this.name = name; }
bool công cộng IsSatisFiedBy (Nhân viên của nhân viên) {return employee.Name == this.name; }
}

NameSpecification spec = new NameSpecification ("Tim");
Nhân viên tim = MyService.GetEmployee (spec);

0

Tôi đồng ý với Stephan: Một nhiệm vụ, một tên phương thức, ngay cả khi bạn có thể thực hiện theo nhiều cách. Tính năng nạp chồng phương thức đã được cung cấp chính xác cho trường hợp của bạn.

  • getEmployeeName (int Id lô)
  • getEmployeeName (String Email)
  • , vv

tránh giải pháp thứ hai của bạn tại tất cả các chi phí. Nó có mùi giống như "khoảng trống cũ của bạn * của C". Tương tự như vậy, việc truyền một đối tượng Java "" gần như là kiểu nghèo như là một "void" C.

0

Nếu bạn có thiết kế tốt, bạn sẽ có thể xác định xem bạn có thể sử dụng cách tiếp cận quá tải hoặc nếu bạn gặp sự cố nếu bạn quá tải, bạn sẽ có hai phương pháp với cùng loại tham số.

Quá tải có vẻ như là cách tốt nhất ban đầu, nhưng nếu bạn không thể thêm phương thức trong tương lai và làm rối tung mọi thứ bằng cách đặt tên, nó sẽ là một rắc rối.

Cá nhân tôi muốn cho cách tiếp cận của một tên duy nhất cho mỗi phương pháp, theo cách đó bạn không gặp phải vấn đề sau này khi cố gắng quá tải cùng một tham số Phương thức đối tượng. Ngoài ra, nếu ai đó mở rộng lớp của bạn trong tương lai và thực hiện một void getEmployeeName (tên String) nó sẽ không ghi đè lên của bạn.

Để tóm tắt, hãy đi với tên phương thức duy nhất cho từng phương pháp, quá tải chỉ có thể gây ra sự cố trong thời gian dài.

1

Tôi sẽ sử dụng tên phương thức rõ ràng. Tất cả mọi người mà duy trì mã và tôi sau đó sẽ hiểu những gì phương pháp đó đang làm mà không cần phải viết bình luận xml.

-1

dính tất cả các tùy chọn của bạn trong một enum, đều có một cái gì đó như sau

+0

Đây là một bảo trì cả cơn ác mộng và triết lý ngược lại của hầu hết các ngôn ngữ hiện tại. Đừng bao giờ bao giờ không bao giờ mã theo cách đó. – paercebal

0

Các tách giữa quá trình tìm kiếm và tiêu chí tìm kiếm jrudolf đề xuất trong ví dụ của mình là tuyệt vời. Tôi tự hỏi tại sao nó không phải là giải pháp bình chọn nhất. Tôi có nhớ gì không

+0

Bởi vì nó là một ý tưởng khung tốt. Nhưng nếu câu hỏi là về quy ước đặt tên của người truy cập, bạn không muốn instanciate 10 đối tượng và thực hiện 10 so sánh, chỉ để có được một số tên. Vì vậy, các "jrudolf" giải pháp có thể được coi là overkill trong hầu hết các trường hợp, và ** thực sự đúng ** trong một số người khác. – paercebal

0

Tôi muốn đi với Query Objects. Chúng hoạt động tốt để truy cập trực tiếp vào bảng. Nếu bạn bị giới hạn trong các thủ tục được lưu trữ, họ mất một số quyền lực của họ, nhưng bạn vẫn có thể làm cho nó hoạt động.

Các vấn đề liên quan