0

Is this considered circular dependency? I don't like that part where I have to pass the object itself to IRule... Is there a way to work around this?

  public interface IRule
  {
    void Apply(World world);
  }

  public class World
  {
    public List<IRule> Rules { get; set; }

    public void ApplyAllRules()
    {
        foreach (var rule in Rules)
        {
            //This is the part that I don't feel good about.
            rule.Apply(this);
        }
    }
  }
omsharp
  • 300
  • 1
  • 13
  • What language is it in? C# I guess? Add a [c#] tag please. –  Dec 12 '14 at 19:46
  • @ciuak, Yes it is, C# – omsharp Dec 12 '14 at 19:47
  • Why do you think this is a problem? – Kirk Woll Dec 12 '14 at 19:52
  • Shouldn't this go to [CodeReview](http://codereview.stackexchange.com/)? – O. R. Mapper Dec 12 '14 at 19:52
  • @KirkWoll, I'm not sure if it's wrong or not really, I just don't like it, and I want to make sure. – omsharp Dec 12 '14 at 19:54
  • Why don't you like it? The interface method `Apply` presumably requires an instance of `World` in order to function, and you're providing it. – Kirk Woll Dec 12 '14 at 19:55
  • Seems fine to me. Have you found a problem with it? – BradleyDotNET Dec 12 '14 at 19:55
  • So this is ok! Isn't this a kind of circular dependency between IRule and World? – omsharp Dec 12 '14 at 19:57
  • No not really, I didn't find any problem so far. – omsharp Dec 12 '14 at 19:58
  • You can add a third type that gets the behavior/attributes you wish to obtain from `World`, gets a list of rules from somewhere (database, factory, etc.) and applies the behavior to the rules. This isn't better, per se, just a different approach. – Tim M. Dec 12 '14 at 19:59
  • Its not really a circular dependency. Sure, they know about each other, but creating a `World` won't create an `IRule` which then creates `Worlds`, etc. You are just passing the `IRule` a reference to it. No problems there. – BradleyDotNET Dec 12 '14 at 19:59
  • This would create a circular dependency if one object or the other was moved to a different assembly however. Personally I think that's a code smell but it all depends on the implementation of `Apply` – moarboilerplate Dec 12 '14 at 20:23
  • 1
    There's really not a problem with this setup. The only thing I would change is to have `IRule.Apply` take an `IWorld` (or some other interface that denotes the dependencies the concrete of `IRule` needs) instead of `World`. – Gjeltema Dec 12 '14 at 20:26

1 Answers1

1

May be I am wrong but term "circular dependency" usually applied to references. What you have here is called "tight coupling". As Gjeltema mentioned, there is not much wrong here besides that preferably, you decouple your concrete objects.

public interface IRule
{
    void Apply(ILocation loc);
}

public class World : ILocation
{
    public List<IRule> Rules { get; set; }

    public void ApplyAllRules()
    {
        foreach (var rule in Rules)
        {

           rule.Apply(this);
        }
     }
 }

Now you have IRule communicating not to concrete object but to abstract interface. So, no 2 or more implementations are tightly coupled.

T.S.
  • 18,195
  • 11
  • 58
  • 78