【问题标题】:Alternatives to pass-by-reference updates on list in JavaJava中列表上的传递引用更新的替代方法
【发布时间】:2021-02-04 16:42:32
【问题描述】:

我有一个有一个或多个输入列表的类,它需要处理和更新其他范围之外的列表。在这里可以使用什么好的模式? 我在这里尝试了以下两种模式:

  1. 使用传递引用直接更新
  2. 使用回调让调用者处理他们希望如何处理更新

示例

  1. 使用直接更新
public class SomeClass {
  public void process(List<String> inputList, List<StringContainer> errorContainerList, List<String> validList) {
    for (String str : inputList) {
      if (someCondition) {
        validList.add(str);
      } else {
        errorContainerList.add(new StringContainer(str, new SomeError()));
      }
    }
  }
}

void someCaller(List<String> inputList) {
    List<String> validList = new ArrayList<>();
    List<StringContainer> errorContainerList = new ArrayList<>();

    SomeClass obj = new SomeClass();
    obj.process(inputList, errorContainerList, validList);

    // Similarly,
    validList.remove(...);
    errorContainerList.add(...);
}
  1. 使用回调
public interface StringErrorHandler {
    void handle(String str, SomeError error);
}

public interface ValidInputHandler {
    void handle(String str);
}

public class SomeClass {
  public void process(List<String> inputList, StringErrorHandler errorHandler, ValidInputHandler validInputHandler) {
    for (String str : inputList) {
      if (someCondition) {
        validInputHandler.handle(str);
      } else {
        errorHandler.handle(str, new SomeError());
      }
    }
  }
}

void someCaller(List<String> inputList) {
    List<String> validList = new ArrayList<>();
    List<StringContainer> errorContainerList = new ArrayList<>();

    SomeClass obj = new SomeClass();
    obj.process(inputList, new StringErrorHandler() {
        
        @Override
        public void handle(String str, SomeError error) {
            errorContainerList.add(new StringContainer(str, error));
        }
    }, new ValidInputHandler() {
        
        @Override
        public void handle(String str) {
            validList.add(str);
        }
    });

    // Similarly,
    validList.remove(...);
    errorContainerList.add(...);
}

【问题讨论】:

  • “好的”模式是什么意思?是什么让模式“好”?
  • 你的这两种方法有什么问题?有例外吗?
  • @Sweeper 由于类似的情况经常发生,我想知道是否有任何我不知道的预先存在的模式。
  • @NomadMaker 第一种方法的问题是,如果输入和输出的数量增加,那么方法的参数数量会增加,这会使重构代码变得更加困难。对于第二种方法,我想知道它是否会使调试变得混乱。

标签: java design-patterns


【解决方案1】:

我不会使用它们。它们都不必要地复杂。让我们想想你的实际问题是什么?如果你不关心错误处理,你可能会这样写:

    public List<String> process(List<String> inputList) {
    List<String> validList = new ArrayList<>();
    for (String str : inputList) {
        if (someCondition) {
            validList.add(str);
        }
    }
    return validList;
}

所以问题是您不能从 java 中的方法返回两个值。但是要处理这个问题,您可以添加一个具有这两个值的简单嵌套类,然后客户端可以轻松地提取它们:

public ProcessResult process(List<String> inputList) {
    List<StringContainer> errorContainerList = new ArrayList<>();
    List<String> validList = new ArrayList<>();
    for (String str : inputList) {
        if (someCondition) {
            validList.add(str);
        } else {
            errorContainerList.add(new StringContainer(str, new SomeError()));
        }
    }
    return new ProcessResult(validList, errorContainerList)
}

public static class ProcessResult{
    public final List<String> validList;
    public final List<StringContainer> errorContainerList;

    public ProcessResult(List<String> validList, List<StringContainer> errorContainerList) {
        this.validList = validList;
        this.errorContainerList = errorContainerList;
    }
}
   void someCaller(List<String> inputList) {
    List<String> validList = new ArrayList<>();
    List<StringContainer> errorContainerList = new ArrayList<>();

    SomeClass obj = new SomeClass();
    ProcessResult pr=obj.process(inputList);
    validList.addAll(pr.validList);
    errorContainerList.addAll(pr.errorContainerList);
    

}

这有几个原因更好,但最重要的是,您的方法没有副作用,并且方法的结果被显式返回,这是我们应该在 java 中做的事情

【讨论】:

  • 在频繁调用的情况下,这个方案会创建很多临时变量(ProcesResult)。您认为这会导致 GC 出现任何问题吗?
  • Java 非常擅长处理冗余对象。 99.999% 的时间你不必考虑这一点,直到你遇到实际的性能问题(检查过早优化)。
猜你喜欢
  • 2017-03-10
  • 1970-01-01
  • 2011-11-28
  • 2015-10-31
  • 2014-09-08
  • 2021-08-08
  • 1970-01-01
  • 1970-01-01
  • 2019-11-02
相关资源
最近更新 更多