I will talk about an antipattern I’ve encountered a few time, but I didn’t find it in literature, so I called it the “Chevron antipattern”. Let-me know if you recognize it and if it has a true name 😉
Let’s start by an example. Assume you develop an application that should support 2 render engines. One, let says, based on Unity and the other based on Unreal, for example. Your 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 Unreal 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.
Why is it an Anti-Pattern ?
The antipattern 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 about 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 a function parameter, but when I encountered this pattern, those usages 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.
How to Fix This ?
This antipattern 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 the 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 having a beautiful class diagram. But this is not a good reason to define an interface.