Пропуск лишней проверки с неизменными маховиками

У меня есть неизменный класс, который выглядит примерно так:

final class Foo {
  private final String name;
  private final MutableObject mo;

  public Foo(String name, MutableObject mo) {
    mo = mo.clone();
    if(!Foo.testValidity(mo)) // this test is very expensive
      throw new IllegalArgumentException();

    this.name = name;
    this.mo = mo;
  }

  public Foo bar(Foo that) {
    return new Foo(this.name, that.mo);
  }
}

bar метод возвращает Foo объект, смешивая внутренности двух существующих Foo объекты. Поскольку MutableObject уже в Foo объект, он гарантированно действителен и не требует копирования или проверки (что в настоящее время делает конструктор).

Поскольку проверка (и, возможно, клон?) Стоят дорого, я бы хотел их избежать, если это возможно. Какой лучший способ сделать это? Это было то, что я придумал:

final class Foo {
  private final String name;
  private final MutableObject mo;

  public Foo(String name, MutableObject mo) {
    this(name, mo, VerificationStyle.STRICT);
  }

  private Foo(String name, MutableObject mo, VerificationStyle vs) {
    if(vs == VerificationStyle.STRICT) {
      mo = mo.clone();
      if(!Foo.testValidity(mo)) // this test is very expensive
        throw new IllegalArgumentException();
    }

    this.name = name;
    this.mo = mo;
  }

  public Foo bar(Foo that) {
    return new Foo(this.name, that.mo, VerificationStyle.LENIENT);
  }

  private static enum VerificationStyle { STRICT, LENIENT; }
}

Я думал, что, по крайней мере, это будет чище / яснее, чем использование фиктивного параметра, и менее подвержен ошибкам, чем подмена порядка, но есть ли лучший способ сделать это? Как это обычно достигается?

1 ответ

Решение

Может быть, полностью скрыть конструктор и создать новые экземпляры, используя метод, подобный фабрике, например:

  private Foo(String name, MutableObject mo) {
    this.name = name;
    this.mo = mo;
  }
  public Foo bar(Foo that) {
    return new Foo(this.name, that.mo);
  }
  public static Foo create(String name, MutableObject mo) {
    mo = mo.clone();
    if(!Foo.testValidity(mo)) // this test is very expensive
      throw new IllegalArgumentException();
    return new Foo(name, mo);
  }
Другие вопросы по тегам