Yep, this would be great in theory…
Indeed, naming design patterns improves readability. This is actually the goal of design patterns in the first place. It's much simpler to say:
I used an abstract factory, but maybe we should start switching to a builder for more flexibility.
to your colleague when explaining the structure of your code, rather than:
I made a parent class which is inherited by a few other classes, given that each of those classes have an intent to create complex objects; now, we should start creating those objects by calling different methods which will progressively extend each object, because it will allow us to customize the way we extend them depending on the circumstances.
The first version is clear (unless the person you speak to has no idea what a factory or a builder is). The second version is difficult to understand and is subject to interpretation.
Enforcing naming conventions for design patterns is useful as well. This would permit the beginners to be accustomed more quickly with those patterns. Learning and applying design patterns is hard, and a help from a static checking tool would greatly improve the learning curve. If you tried to implement a wrapper, but instead created an adapter, static checking tool will show you your mistake, with a bonus point of telling you that you're actually using an adapter.
…but it's hard to do in practice
So, can you enforce naming conventions for design patterns in practice?
I'm not so sure. Here are a few reasons:
A design pattern is easy to understand for an human, but not for a machine. It's not like a strict rule such as "You should always enclose objects which implement
IDisposable into a
using" : such statement is easy to check for an application like FxCop/Code analysis. A design pattern is... well, a pattern. It doesn't have a strict structure; there are multiple ways to implement it, while even slightest changes can destabilize a static checker.
For example, take a strategy pattern. Outside an academic simplistic example, the static checker would have a hard time knowing if the pattern is used or not. Example:
/// <param name="combine">A function which takes two consecutive entries and combines
/// them into a single entry to print.</param>
public void GeneratePdf(
Func<Entry, Entry, ComplexEntry> combine)
The behavior can be switched at runtime by using a different function as an argument of
combine parameter. This doesn't mean that this is a strategy pattern. Maybe in order to combine several entries, some advanced techniques should be used, those techniques being held by the caller library, so using them from the called one is impossible, because of circular dependencies.
In the same way, definitions are not strict enough.
IDisposable rule above is extremely strict. You have an object with a specific interface? Either you put it inside a
using, and the rule will be satisfied, or you don't. Most rules (as well as the one with
IDisposable) have exceptions, but those exceptions are also extremely strict and precise.
Design patterns, on the other hand, have definitions, but those definitions can be bent in order to accommodate different situations. For example, would a
static readonly field be a singleton? What about a property with a backing field and a lock? Those two situations are radically different, and still, they can represent a singleton.
Imagine how hard it would be to check if something is an adapter or a fluent interface. For example, would any method of a class which returns an instance of the class itself be considered a fluent interface?
Static checking is mostly used by developers who know their job. They mostly don't need a tool which would tell that they are using
Strategy keyword, but not using a strategy pattern. Either they are actually using a strategy pattern, and the static checker was wrong, or they are consciously naming the class/method in this way, without any intent of using an actual strategy pattern.
Beginners, i.e. persons who can actually benefit from such static checker, wouldn't use it, because they don't know how to use static checkers, and even if they know, they see such tools more as a disturbance, an annoying thing which bothers them with lots of hard to understand warnings.
To conclude, enforcing naming conventions for design patterns is a difficult task, and would very probably give a lot of false positives and false negatives. It will not be very useful, but may be very annoying instead.
By the way, there is a sort of very smart static checkers: your peers. If somebody misuses a design pattern, it will be highlighted during a code review. Static checkers are excellent to do basic repetitive work, like checking the conformity of the code to strict rules. Keep this basic checking for them, while the choices requiring thinking and making decisions will remain a task of developers checking the code during a code review.