开发者

Is this a Circular dependency?

is this code a example of circular dependency?

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

I know the example is bad programming but doesn't the interface prohibit the circular dependency, due to the value method?


I think it is easier to see in the class diagram. As you can see, there is indeed a circular dependency between Sheet concrete class and Expr interface. I wouldn't say it is VERY bad because I consider circular dependency between 2 concrete classes to be the worst... that said, it is certainly not advisable to do so, if possible.

Your Code

Is this a Circular dependency?

So, perhaps one of the ways you might consider refactoring is to have your AddressExpr to depend on SuperSheet instead of Sheet and Expr to depend on SuperSheet instead of 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);
}

...
...

... and this will remove any unwanted circular dependencies.

Possible Refactored Code

Is this a Circular dependency?

NOTE: I'm not implying this is the solution. I'm just saying you can certainly look at ways to refactor your code to minimize or remove circular dependencies, because circular dependencies make your code difficult to unit test. Coding against interfaces always help to remove unwanted circular dependencies. It also make your code easier to unit test because you can easily mock objects.


This is a really funky example. I'm going to be pretty verbose about my thought process here because I suspect there's some silly naming going on.

Packages: sheet expr

Contents of sheet:

  • Sheet
  • SuperSheet

Contents of expr:

  • AddressExpr
  • Expr
  • Address

Usages in each:

  • AddressExpr - Expr, Address, Sheet
  • Sheet - SuperSheet, Address

We see that AddressExpr depends on Sheet, which is in the sheet package. One dependency down.

We also see that Sheet depends on Address, in the expr package.

Therefore, you have circular dependency between the sheet and expr packages. (Note: Tools can show this. I did it by hand because your problem was pretty abstract. Look into JDepend)

In addition, I'm not even sure that I've ever heard of a value method. If the compiler can make sense of two-way interface use, it'll work. It has the sense to untangle the mess.


At least on package level. Package sheet depends on package expr and vice versa. Based on own experience - I'd refactor this.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜