获取方法:一对多

时间:2020-03-05 18:58:13  来源:igfitidea点击:

getEmployeeNameByBatchId(int batchID)
getEmployeeNameBySSN(Object SSN)
getEmployeeNameByEmailId(字符串emailID)
getEmployeeNameBySalaryAccount(SalaryAccount薪金帐户)

或者

getEmployeeName(int typeOfIdentifier,byte [] identifier)->在此方法中,typeOfIdentifier告诉标识符是否为batchID / SSN / emailID / salaryAccount

以上哪种方法是实现get方法的更好方法?

这些方法将在Servlet中,并从提供给客户的API进行调用。

解决方案

回答

我会采用"许多"方法。对我来说似乎更直观,而且更不容易出错。

回答

为什么不重载getEmployeeName(??)方法?
getEmployeeName(int BatchID)
getEmployeeName(对象SSN)(坏主意)
getEmployeeName(字符串电子邮件)
等等。

对我来说似乎是一个很好的"很多"方法。

回答

我将使用第一个选项,或者在这种情况下将其重载,因为我们有4个不同的参数签名。但是,从现在开始三个月后,具体说明将有助于理解代码。

回答

首选,没问题。要明确。这将大大有助于可维护性,而且实际上没有不利之处。

回答

考虑到它是类型安全的(不同于其他类型),第一个可能是Java中最好的。此外,对于"普通"类型,第二种解决方案似乎只为用户提供了繁琐的用法。但是,由于我们将Object用作SSN的类型(其语义超出了Object的含义),因此我们可能无法避免使用该类型的API。

总而言之,在这种特殊情况下,我会在很多吸气剂中使用这种方法。如果所有标识符都具有自己的类类型,则我可能走了第二条路线,但在类内部进行了切换,而不是使用提供的/应用程序定义的类型标识符。

回答

这些方法中的每种方法的逻辑基本相同吗?

如果是这样,带有标识符参数的单一方法可能更有意义(简单并减少重复代码)。

如果类型之间的逻辑/过程相差很大,则每种类型的方法可能更可取。

回答

@Stephan:一般情况下,这样的情况很难重载,因为参数类型可能没有区别,例如,

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

另请参见原始过帐中的两种方法getEmployeeNameBySSN,getEmployeeNameByEmailId。

回答

正如其他人所建议的那样,第一种选择似乎是不错的选择。当我们编写代码时,第二种可能很有意义,但是当其他人后来出现时,就很难弄清楚如何使用代码。 (我知道,我们有注释,我们可以始终深入研究代码,但是GetemployeeNameById更加不言而喻)

注意:顺便说一句,在某些情况下可能要考虑使用枚举。

回答

我们在考虑C / C ++。

使用对象而不是标识符字节(或者int)。

不好意思,重载方法更好,并且使用SSN作为主键不是很好

public ??? getEmployeeName(Object obj){

if (obj instanceof Integer){

  ...

} else if (obj instanceof String){

...

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

} else throw SomeMeaningFullRuntimeException()

return employeeName
}

我认为最好使用Unchecked Exceptions来表示错误的输入。

记录下来,以便客户知道需要什么对象。或者创建自己的包装器。我更喜欢第一种选择。

回答

在这种琐碎的情况下,我会重载。那是:

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

etc.

仅在特殊情况下,我才会在方法名称中指定参数类型,即,如果难以确定参数的类型,是否有几种类型的参数具有相同的数据类型(batchId和employeeId,都为int),或者对于每种参数类型,检索雇员的方法完全不同。

我不明白为什么我会用这个

getEmployeeName(int typeOfIdentifier, byte[] identifier)

因为它要求被调用方和调用方都基于typeOfIdentifier强制转换值。设计不良。

回答

如果我们重写问题,最终可能会问:

"选择名称自..."
"从...选择SSN"
"选择来自...的电子邮件"

"选择*从..."

而且我猜想答案很简单,每个人都知道。

如果更改Employee类,会发生什么?例如:我们必须删除电子邮件并添加新的过滤器,例如"部门"。使用第二种解决方案,如果我们仅更改int标识符" constants"的顺序,则有很大的风险不注意任何错误。
在第一个解决方案中,我们将始终注意到,如果我们在某些长期被遗忘的类中使用该方法,否则我们将忘记修改为新的标识符。

回答

该方法是使用重载的完美示例。

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

如果方法内部有通用处理,则只需再编写一个getEmplyeeNameImpl(...)并在那里提取通用代码以避免重复

回答

我不喜欢getXByY()在PHP中可能很酷,但我只是不喜欢Java(ymmv)。

我会重载,除非我们具有相同数据类型的属性。在这种情况下,我会执行与第二个选项类似的操作,但不是使用ints,而是使用Enum来确保类型安全性和清晰度。并且我将使用Object(因为自动装箱,这也适用于原语)而不是byte []。

回答

我个人更喜欢使用明确的名称" ... ByRoomNumber",因为如果最终遇到许多"过载",最终将引入不需要的错误。明确是最好的方法。

回答

我们可以使用类似这样的方法:

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

我们获得的类似于Hibernate中的CriteriaAPI。

回答

有时使用规范模式会更加方便。

例如:GetEmployee(ISpecification <Employee>规范)

然后开始定义规格...

名称规格:ISpecification <Employee>
{
私有字符串名称;
public NameSpecification(string name){this.name = name; }
public bool IsSatisFiedBy(Employee employee){return employee.Name == this.name; }
}
NameSpecification spec = new NameSpecification(" Tim");
员工tim = MyService.GetEmployee(spec);

回答

我同意Stephan的观点:一个任务,一个方法名,即使我们可以用多种方法来做。
方法重载功能正是针对情况而提供的。

  • getEmployeeName(int BatchID)
  • getEmployeeName(字符串电子邮件)
  • 等等。

并不惜一切代价避免第二个解决方案。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。闻起来像"你的旧的C的虚空"。同样,传递Java" Object"几乎与C" void *"一样糟糕。

回答

如果我们有一个好的设计,那么我们应该能够确定是否可以使用重载方法,或者是否会遇到一个问题:如果我们重载,那么最终将有两个具有相同参数类型的方法。

最初,重载似乎是最好的方法,但是如果我们最终无法在将来添加方法并弄乱了命名的方式,那将是一件麻烦事。

就我个人而言,我希望为每个方法使用唯一的名称,这样以后我们就不会在尝试重载相同参数的Object方法时遇到麻烦了。另外,如果将来有人扩展类并实现另一个空的getEmployeeName(String name),它将不会覆盖类。

总而言之,为每个方法使用唯一的方法名称,从长远来看,重载只会导致问题。

回答

我将使用显式方法名称。维护该代码的每个人以及我以后的人们都将理解该方法在做什么,而不必编写xml注释。

回答

将所有选项都放在一个枚举中,如下所示

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
}

回答

搜索过程和jrudolf在他的示例中提出的搜索标准之间的脱钩非常好。我想知道为什么它不是投票最多的解决方案。我想念什么吗?

回答

我会去查询对象。它们很好地用于直接访问表。如果我们局限于存储过程,它们会失去一些功能,但是我们仍然可以使它工作。