3

Dependencies are services required by an object to perform its responsibilities. In OOP context it can be thought as a parameter in a constructor.

In my experience I've never found a case for a valid cyclic A <--> B dependency. Every time I find this it turns out to be one of two cases:

  • A and B should actually be a single component (AB)
  • one of components violates single responsibility principle and should be divided into separate ones (A1 --> B --> A2)

To be clear, I'm not talking about cycles in objects used for data structures. I'm interested in components which provide behavior and collaborate between themselves.

Jonas
  • 131
  • 3
  • 1
    http://chat.stackexchange.com/transcript/message/14504253#14504253 – Robert Harvey Mar 26 '14 at 21:38
  • http://en.wikipedia.org/wiki/Mediator_pattern "With the mediator pattern, communication between objects is encapsulated with a mediator object. Objects no longer communicate directly with each other, but instead communicate through the mediator. This reduces the dependencies between communicating objects, thereby lowering the coupling..." – gnat Mar 26 '14 at 21:44
  • Model View Presenter is a common patten that includes cyclic dependencies. – user16764 Mar 27 '14 at 06:10

1 Answers1

6

This is just a self-fulfilling prophecy - whenever you find a cyclic dependency A <--> B where neither A nor B can be split up into smaller components, that gives you a striking argument for having A and B to be combined to single component (AB). As long as you argue that way, you obviously cannot come to a different conclusion.

Lets take a real-world example: Microsofts Scripting Runtime. This library contains components "File" and "Folder". Each File has a parent folder, and each Folder can contain a list of files. So we have indeed a cyclic dependency. Can those two components be split into smaller ones? I guess not without changing the whole semantics. Do they have behaviour? Of course, there are tight to objects in the file system which can be deleted, queried, tested for existence, moved, and so on. Should they be combined into one bigger component? Well, in some sense they are already, they are both part of the FileSystemObject part of the Scripting Runtime, and you cannot reference and use a File or Folder component alone. But now this boils down just to your point of view: on one level of abstraction, these two objects are different components on their own, on another they are not. And you can take this as proof of your hypothesis or a disproof, whatever you like.

Doc Brown
  • 199,015
  • 33
  • 367
  • 565
  • Could you give a simple example of where this prophecy does not appear to be correct? That is, a cyclic dependency that is natural, and merging would be detrimental (or at least pointless)? – Gankro Mar 26 '14 at 21:38
  • @Gankro: see my edit – Doc Brown Mar 26 '14 at 21:53
  • Excellent choice of example! Part of me wants to suggest trying to have Files and Folders implement some common interface so that Folders don't know about Files themselves, but that interface would ultimately need to know about both. – Gankro Mar 26 '14 at 22:41
  • A and B can be combined only if responsibility is the same and not for the sake of removing cyclic dependency. So to me it's not that self-fulfilling prophecy. – Jonas Mar 27 '14 at 09:22
  • 1
    I tried emphasize the meaning of dependency in this context by putting it as a first sentence (but apparently, I failed). Your example with Folder and File is a relationship, but not a dependency: Folder can exist and make sense without any Files, also root Folder can have no parent and still fulfill it's purpose. Dependency in this context is more like Accountant having a dependency on BankAccount because without the dependency accountant's responsibility to transfer money would make no sense, thus Accountant would take BankAccount as a constructor parameter. – Jonas Mar 27 '14 at 09:26