所以我有以下界面:
public interface RoleService {
boolean INCLUDE_DEACTIVE_OBJECTS = true;
boolean EXCLUDE_DEACTIVE_OBJECTS = false;
Set<? extends BaseBusinessObject> getOwnedBusinessObjectsOf(final Employee employee, final boolean includeDeactiveObjects);
}
在上层的某处,示例用法如下..
if (someCondition) {
ownedBusinessObjects = roleService.getOwnedBusinessObjectsOf(employee, RoleService.INCLUDE_DEACTIVE_OBJECTS);
} else {
ownedBusinessObjects = roleService.getOwnedBusinessObjectsOf(employee, RoleService.EXCLUDE_DEACTIVE_OBJECTS);
}
因此,我不是传递true
(或false
)等值,而是在我说INCLUDE_DEACTIVE_OBJECTS
时阅读方法调用要容易得多。
但我不确定,这只是愚蠢吗?这是反模式还是代码气味或某种违反最佳做法的行为?
我认为这类似于以某种方式避免Magic Numbers,但它是否有用或者是否相当令人困惑?
答案 0 :(得分:3)
因为这使API更具可读性,所以没关系。底层值是什么并不重要,重要的是你传递一个触发某种行为的标志。如果您选择的语言仅允许位置参数传递,那么这样的常量使得调用更具可读性。比较:
roleService.getOwnedBusinessObjectsOf(employee, RoleService.INCLUDE_DEACTIVE_OBJECTS);
roleService.getOwnedBusinessObjectsOf(employee, true);
“获取员工拥有的业务对象......什么?”没有人知道“true
”在这里意味着什么,命名值要好得多。
另一种选择是当您选择的语言支持调用时命名参数(此处为Python)时:
roleService.getOwnedBusinessObjectsOf(employee, include_deactivated=True);
API应该在这里强制执行命名参数(再次:Python):
def getOwnedBusinessObjectsOf(employee, *, include_deactivated): ...
在Objective-C中,您可以使用显式方法命名执行类似的操作:
[roleService getOwnedBusinessObjectsOf:employee includingDeactivated:YES]
答案 1 :(得分:1)
在接口中放置常量字段绝对不好,IMO。我来自C#背景,它甚至不允许getOwnedBusinessObjectsIncludingInactive(...)
getOwnedBusinessObjectsExcludingInactive(...)
中的const字段。即使在Java中,您也有Constant Interface(反模式),其唯一目的是包含多个类可以共享的常量。你并不完全是那样做的。仍然只是参考。
所以不要传递诸如true(或false)之类的值,我相信它是 我说的时候,更容易阅读方法调用 INCLUDE_DEACTIVE_OBJECTS
选项1
要在保持可读性的同时替换常量,你可以定义2个方法,这些方法表明是否有效(我会选择'非活动'而不是。它有取消激活动词但没有反应形容词)对象。
RoleService
这些只是private
类中的包装方法,true
分别通过传递false
或getOwnedBusinessObjectsOf(employee, Constants.INCLUDE_INACTIVE_OBJECTS)
getOwnedBusinessObjectsOf(employee, Constants.EXCLUDE_INACTIVE_OBJECTS)
来调用检索实际数据的方法。
选项2
有一个单独的类在一个地方定义应用程序级别常量。
WHERE
答案 2 :(得分:0)
任何采用布尔参数的方法都违反了单一责任原则,因为它为true做了一件事,对于false做了第二件事。
这总是代码味道。 Clean Code告诉我们将方法拆分为两个:
getOwnedBusinessObjectsIncludingDeactiveObjectsOf(Employee employee);
getOwnedBusinessObjectsExcludingDeactiveObjectsOf(Employee employee);
当然,如果要广泛使用该方法,您可能需要更简洁的名称,例如: getAllObjects
和getActiveObjects
。
答案 3 :(得分:0)
如果您不想在常量命名中使用具有相反含义的词,则还可以尝试将布尔值包装到枚举中。
public interface RoleService {
/**
* Boolean wrapper for easy reading of values in method parameters.
*/
enum IncludeDeactiveObjects {
TRUE(true),
FALSE(false);
private final boolean flag;
private IncludeDeactiveObjects(boolean flag) {
this.flag = flag;
}
public boolean get() {
return flag;
}
}
Set<? extends BaseBusinessObject> getOwnedBusinessObjectsOf(final Employee employee, final IncludeDeactiveObjects includeDeactiveObjects);
}
电话为:
roleService.getOwnedBusinessObjectsOf(employee, RoleService.IncludeDeactiveObjects.TRUE);
roleService.getOwnedBusinessObjectsOf(employee, RoleService.IncludeDeactiveObjects.FALSE);
答案 4 :(得分:-1)
如果只是为了可读性,在抽象类中,您可以使用静态变量来保存这些布尔值,并且可以使用ClassName.AttributeName分配
public YourClass
{
public bool static INCLUDE_DEACTIVE_OBJECTS = true;
public bool static EXCLUDE_DEACTIVE_OBJECTS = false;
public static void Main (String args[])
{
}
}