Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating interdependent objects

I have a design problem I cannot find a clean and nice solution to. I am developing in PHP but I believe this could occur in any language. My basic problem is that I have two objects that have circular interdependence at some level of indirection. That means I have a class (call it F) implementing the Facade pattern which contains an object (of class B) which itself needs an object of class A to be created. class A's constructor itself needs a facade F to be created => I have circular interdependence of objects.

I believe I cannot resolve the circular interdependence (the objects basicly implement a finite state machine with a loop using the state pattern) so I am looking for a clean solution. I came up with two possible solutions myself, but I dont think either is especially elegant:

  1. Have class A implement a setFacade(F $facace) method and remove the entire facade from the constructor and just set it after A and the facade are created. Objects of class A cannot work without the facade so this would actually create an object of class A which is not able to do anything until setFacade is called and it would reduce encapsulation and would allow to replace the facade at object runtime, which I also don't like.

  2. Implement something like a Promise that is passed to A instead of the facade which will be able to resolve the facade later as soon it is created. I dont like to introduce this additional indirection layer, especially because I have no good place to actually resolve the promise than in the methods that handle buisness logic inside of A, which could a) produce terrible errors and (more important) b) woul need me to check if the promise was already resolved or if i will need to resolve it now, whenever the buisness logic is called. That's just terrible design in my eyes.

So if anyone can come up with a better solution or could support one of my possible solutions with a good argument I'd really happy.

like image 804
Daniel Baulig Avatar asked Apr 21 '26 00:04

Daniel Baulig


2 Answers

Circular dependencies are such a malicious evil that they must be avoided at all costs, even if it means completely re-thinking your design and throwing away hours of work. (spoken from a maintenance programmer's point of view. Some poor schmuck after you will need to do it anyway.)

There are several ways to look at refactoring code, but the short non-specic advice I have is that any object that is causing a circular dependency should have the offending properties, methods, etc, be split off into a new object. Then each of the two original dependencies would depend on this third object, and not on each other. (And ensure this third object does not depend on the originals.)

Even if it means having duplicate or similar code, it's still better than a circular dependency (but even this should be avoidable with the proper up-front design.)

like image 74
David Avatar answered Apr 23 '26 13:04

David


Assuming you're using the Facade as it's commonly defined (as a simplified interface which manages dependencies and makes it easier to use a complicated API) then none of the "hidden" (by the facade) classes should know of classes which use the facade. Essentially, think of it as a single point of entry, which either means that B shouldn't be dependent on A, or A shouldn't be dependent on the Facade.

like image 21
EricBoersma Avatar answered Apr 23 '26 13:04

EricBoersma



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!