I will talk about an anti-pattern I've encountered a few time but I didn't found it in literature, so I called it the "Chevron anti-pattern". Let-me know if you recognize it and if it has a true name 😉
Lets start by an example. Assume you develop an application that should support 2 render engines. One based on Unity, the other based on Unreal. You render area is embedded in a Window. You define a Widget abstraction layer to handle event, and a Render abstraction layer to handle rendering. You end up with this class diagram:
You have your Windows that has a WidgetInterface which can be either a Unity based widget or an Ureal based widget. Nice, isn't it ?
I called it "Chevron" pattern because one can see 2 chevrons pointing to the top.
And this can continue on several layers.
The anti-pattern part comes from the RendererInterface. An interface defines a set of services that should be implemented by concrete implementation, so that client of this interface don't care of the underlying implementation.
In this case, RendererInterface is not used by any client.
Even if it is not owned by anyone, it may still be used as function parameter, but when I encountered this pattern, those usage could easily be removed with small refactoring.
You end up having very strong constraints on how concrete Unity and Unreal Renderers have to be implemented, without real reasons. Maybe UnityWidget is just a pass-through UnitRenderer, but this design forced you to have such a layer ?
This anti-pattern is very easy to fix if discovered soon enough. If RendererInterface is useless, just remove it:
Now it decouple UnityRender and UnrealRender implementations. You can implement those classes as you want, even merge them into Widget layer if it makes sense. Keep in mind that the important part here is the WidgetInterface. It is this interface that let you change render engine without impacting Windows layer. RendereInterface was initially added probably to keep a symmetry in the design and have a beautiful class diagram, which are not good reason to define an interface.