Получить методы: один против многих - PullRequest
10 голосов
/ 17 сентября 2008

getEmployeeNameByBatchId (int batchID)
getEmployeeNameBySSN (Object SSN)
getEmployeeNameByEmailId (String emailID)
getEmployeeNameBySalaryAccount (SalaryAccount salaryAccount)

или

getEmployeeName (int typeOfIdentifier, byte [] identifier) ​​-> В этих методах typeOfIdentifier сообщает, является ли идентификатор batchID / SSN / emailID / salaryAccount

Какой из вышеперечисленных является лучшим способом реализации метода get?

Эти методы будут в сервлете, и вызовы будут выполняться из API, который будет предоставлен клиентам.

Ответы [ 22 ]

9 голосов
/ 17 сентября 2008

Почему бы не перегрузить метод getEmployeeName (??)?

getEmployeeName (int BatchID)
getEmployeeName (объект SSN) (плохая идея)
getEmployeeName (String Email)
и т.д.

Кажется, хороший подход ко многим.

7 голосов
/ 17 сентября 2008

Вы можете использовать что-то вроде этого:

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));
}

Если вы выполняете фильтрацию по SQL-запросу, вы бы использовали интерфейс Filter для составления предложения WHERE.

Преимущество этого подхода в том, что вы можете легко комбинировать два фильтра с:

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

и используйте это так:

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

То, что вы получаете, похоже на Criteria API в Hibernate.

3 голосов
/ 17 сентября 2008

Мне не нравится getXByY () - это может быть здорово в PHP, но мне просто не нравится в Java (ymmv).

Я бы пошел с перегрузкой, если у вас нет свойств того же типа данных. В этом случае я бы сделал что-то похожее на ваш второй вариант, но вместо использования int я бы использовал Enum для безопасности и ясности типов. И вместо байта [] я бы использовал Object (из-за автобокса это также работает для примитивов).

3 голосов
/ 17 сентября 2008

Я бы пошел с подходом «многие». Это кажется мне более интуитивным и менее подверженным ошибкам.

2 голосов
/ 17 сентября 2008

Методы являются прекрасным примером использования перегрузки.

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

Если у методов есть общая обработка внутри, просто напишите еще один getEmplyeeNameImpl (...) и извлеките там общий код, чтобы избежать дублирования

1 голос
/ 17 сентября 2008

Я буду использовать явные имена методов. Каждый, кто поддерживает этот код, и я позже поймем, что делает этот метод, без необходимости писать xml-комментарии.

1 голос
/ 17 сентября 2008

Первый вариант, без вопросов. Будь явным Это очень поможет в ремонтопригодности, и нет никаких недостатков.

1 голос
/ 17 сентября 2008

Иногда может быть удобнее использовать шаблон спецификации .

Например: GetEmployee (спецификация IS спецификация)

А затем начните определять свои спецификации ...

NameSpecification: ISpecification
{
имя приватной строки;
public NameSpecification (строковое имя) {this.name = name; }
public bool IsSatisFiedBy (сотрудник сотрудника) {возвращать employee.Name == this.name; }
}

NameSpecification spec = новая NameSpecification ("Tim");
Сотрудник tim = MyService.GetEmployee (spec);

1 голос
/ 17 сентября 2008

@ Стефан: трудно перегрузить такой случай (в общем случае), потому что типы параметров не могут быть дискриминационными, например,

  • getEmployeeNameByBatchId (int batchId)
  • getEmployeeNameByRoomNumber (int roomNumber)

См. Также два метода getEmployeeNameBySSN, getEmployeeNameByEmailId в исходном сообщении.

0 голосов
/ 17 сентября 2008

вставьте все ваши варианты в перечисление, у которого есть что-то вроде следующего

GetEmployeeName(Enum identifier)
{
    switch (identifier)
    case eBatchID:
    {
        // Do stuff
    }
    case eSSN:
    {
    }
    case eEmailId:
    {
    }
    case eSalary:
    {
    }
    default:
    {
        // No match
        return 0;
    }
}

enum Identifier
{
    eBatchID,
    eSSN,
    eEmailID,
    eSalary
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...