Singleton
You call Config.getInstance() in the order service, again in the report job, again in three more classes. None of their constructors mention config, yet every one of them quietly depends on the same hidden object.
- ▸One instance does not break tests; the static call that reaches it from anywhere does.
- ▸The naive
if(instance==null)check is a race: two threads both see null, both build, and one becomes two. - ▸A container's single object and a private static field both give one instance; only one shows in the constructor.
Logger.getInstance() hands back the same logger object to whoever calls it. No new, no parameter, no field, you just reach out and the object is there. It feels convenient: the order service logs through it, the report job logs through it, a billing class three folders away logs through it.
Now read those three classes' constructors. Not one of them lists the logger. Their signatures claim they need nothing, yet all three break the moment that logger misbehaves. The dependency is real, it is just invisible, written as a static call buried inside a method instead of declared up front.
That is the catch with reaching for a single shared object through a static call. The object's reach is unlimited and its dependents are untracked. You cannot look at a class and know whether it touches the shared thing; you have to grep every method body. Try to swap the object for a test double and there is no seam to swap it at, the call site names a concrete class, not a parameter you control.
The viz puts the shared object in the center and the call sites around it. The wires that bind them stay hidden until you toggle them on, exactly as they are hidden in the code.