获取方法:一对多
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中的Criteria
API。
回答
有时使用规范模式会更加方便。
例如: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在他的示例中提出的搜索标准之间的脱钩非常好。我想知道为什么它不是投票最多的解决方案。我想念什么吗?
回答
我会去查询对象。它们很好地用于直接访问表。如果我们局限于存储过程,它们会失去一些功能,但是我们仍然可以使它工作。