In short
It's just an ambiguity in the human language.
More arguments
Factory methods can be abstract
The pattern where a factory creates a single product is the GoF's Factory Method pattern, which matches the design of ILoggerFactory
:
Define an interface for creating an object, but lets the subclass decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
The main issue with this pattern is its ambiguous naming, which suggests it's about a method, whereas in reality it's about a factory. So people often use the shortcut "Factory". And in modern programming languages, the factory is in general defined as an interface, so an abstraction without implementation. This makes the "Factory", technically speaking, an "abstract factory" in the OOP meaning, not in the GoF meaning. So the use of this terminology is perfectly valid.
Abstract factories could be about a single product
Let's look at the intent of abstract factories with a slightly different emphasis:
Provide an interface for creating families of related or dependent objects without specifying their concrete classes.
Here it's about decoupling the creation of abstract objects from their concrete implementation. Interestingly, everything in this design is about abstracting products to be created, and hence abstracting their creation. Unlike the factory method, where the factory can delegate the choice of the product to a subclass or implement a default choice (i.e. use a concrete product rather than an abstract one), the abstract factory must delegate the creation of the products to a concrete factory (since it is not possible to instantiate abstract products).
Nothing in the design of this pattern requires more than one abstract product. The only ambiguity is the use of the term "families of related objects", which is not technically well defined and may suggest that it is more than one. But if the more neutral term of "group" or "set" would be used instead, nobody would argue about the validity to have only one abstract product in the "group"/"set" with only one member.
With this interpretation, the ILoggerFactory
would also match the definition of an abstract factory, this time from a GoF point of view.
Some more arguments about GoF context
The GoF did not require the factory method TO BE an interface but TO DEFINE an interface. The GoF allows for example the Factory Method to be defined as a class that propose a default implementation (which is possible only if the product is itself not abstract). GoF also proposes implementation variants that avoid using abstract methods completely. Last but not least GoF also mentions implementation where the product class embeds a factory method. So some of the proposed approach of the factory pattern differ more substantially from the GoF's abstract factory.
But in the context of DI, the Factory Method is always an interface and hence eligible for being called "abstract factory" and there is an overlap with the abstract factory pattern.
Also, GoF aims to provide solution for common problems. And the possibility of having several families of related products that interact between them and require some compatibility is quite common. Not mentioning families in plural in the abstract factory would have missed this specific use case.