Является ли это циркулярной зависимостью?
является ли этот код примером циклической зависимости?
package expr;
import sheet.Sheet
public class AdressExpr implements Expr
{
private Address address;
private Sheet sheet;
public double value(Sheet sheet)
{
return sheet.value(address);
}
}
public interface Expr
{
public double value(Sheet sheet);
}
public class Adress
{
// omissions
}
package sheet;
import expr.Address;
import expr.Expr;
public class Sheet implements SuperSheet
{
private Map <Address, Expr> map;
public double value(Address address)
{
return map.get(Address).value(this);
}
}
public interface SuperSheet
{
public double value(Address address);
}
Я знаю, что пример - плохое программирование, но не запрещает ли интерфейс циклическую зависимость из-за метода значений?
Ответы
Ответ 1
Я думаю, что легче увидеть на диаграмме классов. Как вы можете видеть, действительно существует круговая зависимость между Sheet
конкретным классом и интерфейсом Expr
. Я бы не сказал, что это ОЧЕНЬ плохо, потому что я считаю, что круговая зависимость между двумя конкретными классами является наихудшей... что, конечно, не рекомендуется делать это, если это возможно.
Ваш код
![enter image description here]()
Итак, возможно, один из способов, по которым вы можете подумать о рефакторинге, - это зависеть < SuperSheet
от SuperSheet
вместо Sheet
и Expr
от SuperSheet
вместо Sheet
: -
public class AdressExpr implements Expr {
private Address address;
private SuperSheet sheet;
public double value(SuperSheet sheet) {
return sheet.value(address);
}
}
public interface Expr {
public double value(SuperSheet sheet);
}
...
...
... и это устранит любые нежелательные круговые зависимости.
Возможный восстановленный код
![enter image description here]()
ПРИМЕЧАНИЕ. Я не подразумеваю, что это решение. Я просто говорю, что вы можете, конечно, посмотреть, как реорганизовать ваш код, чтобы свести к минимуму или удалить круговые зависимости, потому что круговые зависимости затрудняют ваш код unit test. Кодирование по интерфейсам всегда помогает удалить нежелательные круговые зависимости. Это также упростит ваш код unit test, потому что вы можете легко имитировать объекты.
Ответ 2
Это действительно забавный пример. Я собираюсь быть довольно подробным о моем мыслительном процессе здесь, потому что я подозреваю, что там происходит глупое именование.
Пакеты:
лист
выражение
Содержание листа:
Содержимое expr:
Использование в каждом:
- AddressExpr - Expr, адрес, лист
- Лист - SuperSheet, Адрес
Мы видим, что AddressExpr зависит от Листа, который находится в пакете листов. Одна зависимость ниже.
Мы также видим, что Лист зависит от адреса, в пакете expr.
Следовательно, у вас есть круговая зависимость между листом и пакетами expr. (Примечание: инструменты могут показать это. Я сделал это вручную, потому что ваша проблема была довольно абстрактной. Посмотрите на JDepend)
Кроме того, я даже не уверен, что когда-либо слышал о методе значений. Если компилятор может понять смысл использования двухстороннего интерфейса, он будет работать. У него есть смысл распутать беспорядок.
Ответ 3
По крайней мере, на уровне пакета. Пакет sheet
зависит от пакета expr
и наоборот. Основываясь на собственном опыте - я бы реорганизовал это.