如何重构以避免传递;“特殊价值观”;转换成Java方法?

如何重构以避免传递;“特殊价值观”;转换成Java方法?,java,Java,我确信一定有一个标准的方法可以做到这一点,但是我尝试搜索Stackoverflow失败了 我有这样一种方法: public void processSomeWidgetsForUser(int userItemId) { Iterator<Widgets> iter = allWidgets.values().iterator(); while(iter.hasNext()) { Widget thisWidget = iter.next();

我确信一定有一个标准的方法可以做到这一点,但是我尝试搜索Stackoverflow失败了

我有这样一种方法:

public void processSomeWidgetsForUser(int userItemId) {
    Iterator<Widgets> iter = allWidgets.values().iterator();
    while(iter.hasNext()) {
        Widget thisWidget = iter.next();
        if (userItemId == -1 || thisWidget.getUsersItemId() == userItemId) {                 
             widget.process();
        }
    }
}
public void进程somewidgetsforuser(int-userItemId){
迭代器iter=allWidgets.values().Iterator();
while(iter.hasNext()){
Widget thisWidget=iter.next();
如果(userItemId=-1 | | thisWidget.getUsersItemId()==userItemId){
widget.process();
}
}
}
正如您所看到的-1是一个“特殊值”,表示所有过程。这样做可以避免在另一个名为processSomeWidgetsForAllUsers的方法中重复循环代码

但我不喜欢这样的特殊值,因为它们很容易被误用或误解,这正是我现在必须解决的问题(有人认为-1意味着其他东西)

我只能想出两种方法来改善这一点

  • 有一个常数,包含-1,叫做 Widget.ALLWIDGETS,至少是自文档化的,但不是 停止代码使用-1(如果有人在中集成了旧代码,例如 (示例)
  • 更改该方法以将所有用户ID的列表 进程,它可以是空的,但看起来不太好 性能方面(需要首先检索所有用户ID,然后循环 删除。如果列表中的小部件数量在 检索ID并删除
  • 有更好的办法吗?我肯定我错过了一些明显的东西


    上面的代码已经稍作更改,因此可能无法编译,但您应该了解要点。

    第1项将非常有效。请确保记录变量是什么,以便未来的编码人员(可能是您自己)知道它的含义

    /**This is the explanation for the below variable*/
    public final static int ALL_WIDGETS = -1;
    

    有这样一种外部方法:

    static boolean idRepresentsAll(int id) {
        return id == -1;
    }
    
    在这种情况下,如果您决定用一种不同的机制替换它,那么您只需替换代码中的第一个神奇位置

    至少,你会想这样做:

    public static final int ID_REPRESENTING_ALL = -1;
    

    虽然有些冗余,但一个相当整洁的自我记录方法可能是有3种方法,而不是一种

    将您原来的方法
    设为private
    ,并做一个小小的更改,即添加您的
    static final int EXECUTE\u ALL=-1
    ,并在您原来的方法中使用它,然后添加两个新方法

    public void processWidget(int wID) throws IllegalArgumentException {
        if(wID == EXECUTE_ALL) throw new IllegalArgumentException();
        originalMethod(wID);
    }
    
    public void processAllWidgets() {
        originalMethod(EXECUTE_ALL);
    }
    
    这会使您的类更加混乱,但就公开的方法而言,它更清晰,并且希望是万无一失的。您可以更改它,使其不引发异常,只忽略任何无效ID,这取决于您的情况


    当然,这种方法的主要缺点是它改变了类在其他类中的显示方式,打破了当前使用的、现在是私有的originalMethod()。

    您可以更改方法签名,以便在希望处理它们时接受布尔值

    public void processSomeWidgets(boolean doAll, int userItemId) {
        Iterator<Widgets> iter = allWidgets.values().iterator();
        while(iter.hasNext()) {
            Widget thisWidget = iter.next();
            if (doAll || thisWidget.getUsersItemId() == userItemId) {                 
                 widget.process();
            }
        }
    }
    
    public void processSomeWidgets(布尔doAll,int userItemId){
    迭代器iter=allWidgets.values().Iterator();
    while(iter.hasNext()){
    Widget thisWidget=iter.next();
    如果(doAll | | thisWidget.getUsersItemId()==userItemId){
    widget.process();
    }
    }
    }
    

    这使得它更明确,在我看来更容易阅读,因为没有特殊的值。

    我更喜欢这种方法,因为它更清晰(没有幻数),但我只会对任何已知的无效id抛出一个IllegalArgumentException。不需要检查异常(但javadoc限制了输入).谢谢-这很好地处理了错误的呼叫,而且很清楚。