Pull to refresh

Comments 11

Остается только один вопрос. Какой процент современных энтерпрайзных джава-проектов реально использует "богатую" доменную модель, в которой в принципе возможна описанная проблема с наследниками Account?

Нарушение LSP в виде выкидывания исключений я бы ожидал увидеть даже в самой бедной доменной модели. Это не значит, что оно там будет — но кодить, как по мне, нужно сразу с учетом того, что оно таки будет иметь место.

Интересно про запахи плохого кода. Описание Вы дали (не совсем я согласен), но как решить проблему - осталось "за кадром".

Метод подтипа постоянно возвращает одно и то же значение

Чем

class Parent {
  abstract int getValue();
}

class Child0 extends Parent {
  int getValue() {
    return 0;
  }
}

class Child1 extends Parent {
  int getValue() {
    return 1;
  }
}

хуже

class Parent {
  int value;
  
  Parent(int v) {
    this.value = v;
  }
  
  int getValue() {
    return this.value;
  }
}

class Child0 extends Parent {
  Child0() {
    super(0);
  }
}

class Child1 extends Parent {
  Child1() {
    super(1);
  }
}

Ничем, это признак может давать ложно-положительные срабатывания.

7.1. Подтип бросает исключение для поведения, которое он не может выполнить


Один из вариантов решения, сделать это исключение частью контракта.
Формально может правило и не нарушенно, но по факту все проблемы которые это нарушение добавляет имеются, потому что никто этих контрактов не читает.

https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Collections.html
The "destructive" algorithms contained in this class, that is, the
algorithms that modify the collection on which they operate, are specified
to throw UnsupportedOperationException if the collection does not
support the appropriate mutation primitive(s), such as the set
method. These algorithms may, but are not required to, throw this
exception if an invocation would have no effect on the collection. For
example, invoking the sort method on an unmodifiable list that is
already sorted may or may not throw UnsupportedOperationException.

Какая реакция предполагается, если запрошенная сумма списания превысит остаток по счёту?

Уж лучше жестко связанный код, чем ансаппортед оперейшн. ООП головного мозга. Очень удобно.

При этом бизнес-логика все-равно будет обернута ифами/кетчами и по факту будет знать про реализации.

А можно объяснить чем плохо добавить в изначальный класс Account предупреждение о том что может быть ошибка, и обработать ошибку внутри BankingAppWithdrawalService?

Ну или можно сделать что то на подобии метода попытку снятия откуда возвращать успешность операции?

Простите, но что дает SOLID в данном примере с аккаунтами? Идею абстрактного класса, наследования и дерева классов ввели в оборот задолго до книги Мартина. Собственно, ООП и предполагает такую иерархию. ООП и был спроектирован и разработан в расчете на это. Класс, работающий с абстрактным классом, ничего не знает о подклассах и все такое. В любом учебнике по ООП двадцатилетней давности будет представлен этот пример с аккаунтами. С автомобилями. Это студенческие примеры для обучения азам ООП.

При чем тут SOLID вообще, Мартин и его книга в частности? Из статьи, к сожалению, не понятно, что полезного добавляет SOLID к парадигме ООП.

Sign up to leave a comment.

Articles