Это круговая зависимость? - PullRequest
       29

Это круговая зависимость?

10 голосов
/ 14 февраля 2011

является ли этот код примером циклической зависимости?

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);
}

Я знаю, что это плохое программирование, но разве интерфейс не запрещает циклическую зависимость из-за метода значений?

Ответы [ 3 ]

6 голосов
/ 14 февраля 2011

Я думаю, это легче увидеть на диаграмме классов. Как видите, действительно существует круговая зависимость между Sheet конкретным классом и Expr интерфейсом. Я бы не сказал, что это ОЧЕНЬ плохо, потому что я считаю, что круговая зависимость между двумя конкретными классами является наихудшей ... тем не менее, делать это, по возможности, не рекомендуется.

Ваш код

enter image description here

Итак, возможно, один из способов, с помощью которого вы можете подумать о рефакторинге, это заставить ваш AddressExpr зависеть от 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

ПРИМЕЧАНИЕ : Я не имею в виду, что это решение. Я просто говорю, что вы, безусловно, можете найти способы реорганизации вашего кода для минимизации или удаления циклических зависимостей, потому что циклические зависимости затрудняют ваш код для модульного тестирования. Кодирование на основе интерфейсов всегда помогает удалить нежелательные циклические зависимости. Это также облегчит ваш код для модульного тестирования, потому что вы можете легко макетировать объекты.

3 голосов
/ 14 февраля 2011

Это действительно прикольный пример. Я собираюсь быть довольно многословным о моем мыслительном процессе здесь, потому что я подозреваю, что происходит какое-то глупое наименование.

Пакеты: простынь выраж

Содержание листа:

  • лист
  • SuperSheet

Содержание expr:

  • AddressExpr
  • Expr
  • Адрес

Использование в каждом:

  • AddressExpr - Expr, Address, Sheet
  • Sheet - SuperSheet, адрес

Мы видим, что AddressExpr зависит от Sheet, который находится в пакете листов. Одна зависимость вниз.

Мы также видим, что Sheet зависит от Address, в пакете expr.

Таким образом, у вас есть круговая зависимость между листом и пакетами expr. (Примечание: инструменты могут показать это. Я сделал это вручную, потому что ваша проблема была довольно абстрактной. Посмотрите на JDepend)

Кроме того, я даже не уверен, что когда-либо слышал о методе значений. Если компилятор может использовать двусторонний интерфейс, он будет работать. Имеет смысл распутывать беспорядок.

2 голосов
/ 14 февраля 2011

Как минимум на уровне пакета.Пакет sheet зависит от пакета expr и наоборот.Основываясь на собственном опыте - я бы рефакторинг это.

...