Why Parameterless factory methods are Leaky Abstraction? [closed] - c#

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
I'm reading a book which says:
// code smell
public interface IProductRepositoryFactory {
IProductRepository Create();
}
The Dependencies created by an Abstract Factory should conceptually require a runtime value, and the translation from a runtime value into an Abstraction should make sense.
By specifying an IProductRepositoryFactory Abstraction with a parameterless
Create method, you let the consumer know that there are more instances of the given
service, and that it has to deal with this. Because another implementation of IProductRepository might not require multiple instances or deterministic disposal at all,
you’re therefore leaking implementation details through the Abstract Factory with its
parameterless Create method.
I'm a little bit confused here, what does "more instances of the given service" mean, does it mean that you call a concrete Factory's Create method multiple times? what's wrong with that? even if you have factory methods that does have parameters as:
public interface IProductRepositoryFactory {
IProductRepository Create(string type);
}
and if you call a concrete Factory's Create method multiple times there will be multiple instances too. so what's wrong with parameterless factory methods? what does it leak?

An abstraction is "leaky" when it fails to hide details of the underlying implementation that it is supposed to hide.
It isn't true that a parameterless factory method is always leaky, because that of course depends on what the abstraction it returns is supposed to hide, and the author you reference never really specifies what information details are exposed that are supposed to remain hidden.
But what he says is often correct. If you provide this IProductRepositoryFactory method, then the receiver can create as many instances of IProductRepository as it likes... but why would the receiver want to make one, or two, or a bunch? If you pass this factory interface, then the choice is probably important. The receiver must know about the kinds of trade-offs involved in making one instance vs. many. It probably has to do with caching, thread pooling, etc.
Often, this is the kind of implementation detail that the receiver should not have to know about.
But, you know...
It is actually pretty common and perfectly fine under many circumstances to inject interfaces that look a lot like this case, and this gets into fussing about the definitions of words.
For instance, you might pass in a factory that the receiver would use like this:
factory.createDocument().setTitle(title).setContent(content).save();
Perfectly fine. What's the difference? Well, in this case it's that the document we're creating is not a "Dependency". The factory itself is the dependency. The service it provides is the ability to create documents, which the caller will then own. These documents are obviously stateful and have identity. This is not something that the Document abstraction is supposed to hide at all, and so this is not a leaky abstraction.
Similar patterns happen a lot when working with multithreaded code. You will quite often have a thread-safe factory service that creates objects that are not thread-safe.

does it mean that you call a concrete Factory's Create method multiple times? what's wrong with that?
Well, their point is that you don't know what to do with the product repository. Is it a singleton? Then it should be an actual singleton instance, not coming from a factory. Is it disposable? Well, you're returning a IProductRepository, not an IDisposable, so there's nothing to suggest that you should be disposing that.
even if you have factory methods that does have parameters [...] if you call a concrete Factory's Create method multiple times there will be multiple instances too
I believe their thinking is that you'd be getting already built instances based on your parameters that are cached between runs, so there's no disposing involved.
I'm not sure I fully agree with their thinking, but I will say that in my opinion you'll never sell this pattern to me. Either use a singleton, or dependency injection (which supersedes singletons as well).

To address this question properly really requires reading the full article for any readers of the answers here to have the necessary context. In terms of the specifics of your particular question, here's some clarification on the concerns that are raised:
Injecting the factory instead of the service itself puts the onus of lifetime management of the dependency (IProductRepository) on the consumer (HomeController). If the dependency was injected instead of the factory, a proxy class or the IoC framework could be charged with lifetime management, freeing up the consumer to focus on working with the API surface of the dependency.
Use of a proxy repository class could further limit the leak, as IDisposable would no longer be implemented by IProductRepository nor exposed to the consumer since the proxy would manage lifetime.
The Create method of the factory implies that multiple instances of whatever implementation is being handed back can be created. Again, this places extra and unnecessary responsibility on the consumer to manage- or at least be concerned with this when it could be handled elsewhere. As pointed out in Matt's answer there are circumstances where it's perfectly fine- if not expected- to be able to generate more than one instance from a factory. In the article in question it's really a matter of the repository pattern and the conventions that come with it that makes the design awkward; typically it doesn't make sense to have multiple instances of a given type of repository but by injecting the factory instead of the factory instance, the code allows this thus creating the leak.
Overall, most of the concern here revolves around the fact that a factory is being injected as a dependency instead of the dependency itself which ultimately requires more knowledge of the dependency than is necessary on the consumer end. The parameterless factory method returning an abstraction further compounds this. If some runtime information needed to be provided in order for that factory to make a decision as to what concrete type to instantiate and hand back as an abstraction, injecting the factory would make more sense. As it stands it's just not great design, and poor design can lead to additional mental overhead. The fact that the Create method hands back an interface instance instead of a concrete instance without accepting any parameters might a) raise questions as to why the factory would hand back an instance of one type or another, thus requiring knowledge of how the factory makes its decisions, or b) require knowledge of the fact that there is only one implementation of IProductRepository. Neither of these are anything that the consumer, or the developers leveraging the dependency, should really have to concern themselves with. A proper abstraction combined with proper IoC mitigates these concerns.

Related

Dependency Injection vs Abstract Factory - choosing the right pattern [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I'm developing tool that migrates issues from old to new issue tracking system. I have separated everything with interfaces, but I'm not sure what's the best way to glue it back together. I have 3 dependencies, that require runtime data:
INewSystemClient - client to connect to new system
IRetryStrategy - handles timeouts and retries
IMigrationSettings
These 3 dependencies are dependencies of many others. I couldn't figure out other way to glue everything, than registering these 3 as singletons (via DI container). I also know, that singletons are considered a bad pattern, so I'm considering switching to abstract factory.
Example relationship which forced me to use singleton:
Dependency1(INewSystemClient client, ...) // constructor for Dependency1
Dependency2(INewSystemClient client, ...) // constructor for Dependency2
INewSystemClient requires runtime data like user, pw, host etc.
Should I switch to abstract factory and make factory create objects instead of DI container?
I think you are confusing terms just like a Singleton pattern (most say it's an anti-pattern now) is not the same as a singleton instance in your IOC, an Abstract factory pattern is not the same as a DI factory. What you need to think about is scopes or when the object is created and disposed.
In your desktop app there can be multiple scopes in which you can register an object (On an App level or "a singleton", on a Module level, on a thread level, on a Page level...) This usually depends on the framework you are using (Prism, MvvmLight, caliburn.micro...) if you are building you own system you might want to look how some of the other frameworks did it.
I know Unity has a cool way of handling factories and lazy initializations.
Usually a singleton instance is best used for stuff that won't be accessed in multiple threads that will change some values. This is when you need to create locks and you can slow things down in a big way like blocking your UI thread. For example if you have an HttpClient that just call a single backend api that every one can use it would make sense to make it a singleton scope.
If for example you want to write to a database you might want to have a different EF context per page so the entity tracking doesn't happen on two page.
I have 3 dependencies, that require runtime data:
From your question it is unclear how those dependencies consume runtime data. If they require it during initialization, that's a code smell. If you are passing along that runtime data through method calls on already initialized (and immutable) classes, that's completely fine.
I also know, that singletons are considered a bad pattern, so I'm considering switching to abstract factory.
Filip Cordas already touched this, but I like to repeat: You are confusing two things. When it comes to applying DI, the Singleton Pattern is a bad thing, but having a single instance of some class at runtime (a.k.a. the Singleton Lifestyle) is completely fine. Some (like me) prefer making all components to be registered with the Singleton Lifestyle, since this forces immutability and statelessness, which simplifies registration and prevents all kinds of common misconfigurations, such as Captive Dependencies.
Should I switch to abstract factory and make factory create objects instead of DI container?
As explained here, Abstract Factories are typically not the right solution, and I consider them a code smell. They are typically used to build up application components using runtime data, but as stated earlier, application components should not require runtime data during construction.

Dependency injection: single class (WCF service) having multiple dependencies (DB repositories) how to handle?

I've read a book "Dependency injection in .NET" by Mark Seemann and it opened my eyes on many things. But still few question left. Here is one of them:
Let's say we have a WCF service exposing API for working with some database:
public class MyService : IMyService
{
private ITableARepository _reposA;
private ITableARepository _reposB;
//....
public IEnumerable<EntityA> GetAEntities()
{
return _reposA.GetAll().Select(x=>x.ToDTO())
}
public IEnumerable<EntityB> GetBEntities()
{
return _reposB.GetAll().Select(x=>x.ToDTO())
}
//...
}
There may be dozens of repositories service depend on. Some methods use one, some methods another, some methods use few repositories.
And my question is how to correctly organize injection of repository dependencies into service?
Options I see:
Constructor injection. Create a huge constructor with dozens of arguments. Easy for usage, but hard for managing parameters list. Also it's extreemely bad for performance as each unused repository is a waste of resources even if it doesn't use separate DB connection.
Property injection. Optimizes performance, but usage becomes non-obvious. How should creator of the service know which properties to initialize for specific method call? Moreover this creator should be universal for each method call and be located in the composition root. So logic there becomes very complicated and error-prone.
Somewhat non-standard (not described in a book) approach: create a repository factory and depend on it instead of concrete repositories. But the book say factories are very often used incorrectly as a side way to overcome problems that can be resolved much better with proper DI usage. So this approach looks suspicious for me (while achieving both performance and transparency objectives).
Or is there a conceptual problem with this relation 1 to many dependencies?
I assume the answer should differ depending on service instance context mode (probably when it's Single instance, constructor injection is just fine; for PerCall option 3 looks best if to ignore the above warning; for perSession everything depends on the session lifetime: whether it's more close to Single instance or PerCall).
If it really depends on instance context mode, then it becomes hard to change it, because change requires large changes in the code (to move from constructor injection to property injection or to repository factory). But the whole concept of WCF service ensures it is simple to change the instance context mode (and it's not so unlikely that I will need to change it). That makes me even more confused about DI and WCF combination.
Could anyone explain how this case should be resolved correctly?
Create a huge constructor with dozens of arguments
You should not create classes with a huge number of constructor arguments. This is the constructor over-injection code-smell. Having constructors with a huge amount of arguments is an indication that such class does too much: violates the Single Responsibility Principle. This leads to code that is hard to maintain and extend.
Also it's extremely bad for performance as each unused repository is a waste of resources
Have you measured this? The amount of constructor arguments should be mainly irreverent for the performance of the application. This should not cause any noticeable difference in performance. And if it does, it becomes be time to look at the amount of work that your constructors do (since injection constructors should be simple) or its time to switch to a faster DI container if your constructors are simple. Creating a bunch of services classes should normally be blazingly fast.
even if it doesn't use separate DB connection.
The constructors should not open connections in the first place. Again: they should be simple.
Property injection. Optimizes performance
How should creator of the service know which properties to initialize for specific method call
The caller can't reliably determine which dependencies are required, since only constructor arguments are typically required. Requiring properties results in temporal coupling and you lose compile-time support.
Since the caller can't determine which properties are needed, all properties need to be injected and this makes the performance equivalent as with constructor injection, which -as I said- should not be a problem at all.
Somewhat non-standard (not described in a book) approach: create a repository factory and depend on it instead of concrete repositories.
Instead of injecting a repository factory, you could inject a repository provider, a pattern which is better known as the Unit of Work pattern. The unit of work may give access to repositories.
I assume the answer should differ depending on service instance context mode
No, since you should never use the WCF 'Single' mode. In most cases the dependencies you inject into your WCF services are not thread-safe and should not outlive a single request. Injecting them into a singleton WCF service causes Captive Dependencies and this is bad because it leads to all kinds of concurrency bugs.
The core problem here seems that your WCF Service classes are big and violate the Single Responsibily Principle, causing them to hard to create, maintain, and test. Fix this violation by either:
Splitting them up in multiple smaller classes, or
Moving functionality out of them into aggregate services and apply patterns such as the command/handler and query/handler patterns.

Why shouldn't I call my dependencies from within the constructor?

I've long considered it a bad practice to call out to a classes dependencies from within the constructor but wasn't able to articulate why to a colleague yesterday. Can anyone provide a good reason for NOT doing this?
There are several reasons for Nikola Malovic's 4th law of IoC:
When we compose applications with Constructor Injection we often create substantial object graphs, and we want to be able to create these graphs as efficiently as possible. This is Nikola's original argument.
In the odd (and not recommended) cases where you have circular dependencies, the injected dependencies may not yet be fully initialized, so an attempt to invoke their members at that time may result in an exception. This issue is similar to the issue of invoking virtual members from the constructor. Conceptually, an injected dependency is equivalent to a virtual member.
With Constructor Injection, the constructor's responsibility is to demand and receive the dependencies. Thus, according to the Single Responsibility Principle (SRP), it should not try to do something else as well. Some readers might argue that I'm misusing the SRP here, but I think I'm simply applying the underlying principle in a more granular context.
Please notice that this rule is contextual: it applies to Services that use Constructor Injection. Entities and Value Objects tend not to use DI, so their constructors are covered by other rules.
If you call out to your dependencies, you're actually doing work in a constructor.
From a client's perspective that is unexpected. When I do something like this:
var myObj = new SomeClass();
I don't expect any side-effects.
If you do things in the constructor, for example it could throw an exception, which is certainly not what you expect. It's like naming a method FetchUsers and inside that method creating a user and returning it. Not what you'd expect.

In which cases it makes sense to use factory classes instead of static functions?

Currently I have created a ABCFactory class that has a single method creating ABC objects. Now that I think of it, maybe instead of having a factory, I could just make a static method in my ABC Method. What are the pro's and con's on making this change? Will it not lead to the same? I don't foresee having other classes inherit ABC, but one never knows!
Thanks
Having a single, static method makes this much more difficult to test whereas having an instantiable object allows this to be easier to test. Also, dependency injection is later more of an option with the non-static solution.
Of course, if you don't need any of this, then these are not good arguments.
The main advantage of the factory method is the ability to hide reference to a specific class behind an interface. Since static methods can not be a part of the interface, static factory methods are basically the same as the constructor method itself. The only useful application of the static factory methods is to provide access to a private constructor - what is commonly used for singleton-pattern implementation.
In reality, if you want to get the benefits of a factory class, you need the static method in it's own class. This will allow you to later create new factory classes, or reconfigure the existing one to get different behaviors. For example, one factory class might create Unicorns which implement the IFourHoovedAnimal interface. You might have an algorithm written that does things with IFourHoovedAnimal's and needs to instantiate them. Later you can create a new factory class that instead instantiates Pegasus's which also implement IFourHoovedAnimal's. The old algorithm can now be reused for Pegasus's just by using the new factory! To make this work both the PegasusFactory and the UnicornFactory must inherit from some common base class(usually an abstract class).
So you see by placing the static method in it's own factory class, you can swap out factory classes with newer ones to reuse old algorithms. This also works for improving testability, because now unit tests can be fed a factory that creates mock objects.
I have done the latter before (static factory method on the class that you are creating instances of) for very small projects, but it was only because I needed it to help refactor some old code, but keep changes to a minimum. Basically in that case I had factored out a chunk of code that created a bunch of ASP.NET controls, and stuff all those controls into a user control. I wanted to make my new user control property based, but it was easier for the old legacy code to create the user control with a parameter based constructor.
So I created a static factory method that took all the parameters, and then instanced the user control and set it's properties based on the parameters. The old legacy code used this static method to create the user control, and future code would use the "prettier" properties instead.
For concrete classes, factory methods are really just a method of indirection around creating the actual type (which isn't to say they aren't useful, but as you've found, the factory method could really be anywhere).
Where the factory method really shines though is when your method creates instances of an interface type.
The "D" in Uncle Bob's SOLID Principles of Object Oriented Design is "The Dependency Inversion Priciple" Depend on abstractions, not on concretions.
An extreme following of that principle could have your main class create all your factories, with each factory using other factories via interfaces. The only appearance of "new" (creating concrete objects) would be in your main class, and your factories. All your objects would work with interfaces (abstractions), with the concrete dependencies obtained from supplied factory implementations.
You could then very easily adjust, or provide multiple Main classes customised for different scenarios.
Overuse of design patterns are dangerous, and creational design patterns make sense when you have class hierarchies with defined interfaces, or need to build rather complex objects. If you have a simple design, use simple solutions. Therefore, in your case, Factory Method would be enough
Yes, you are right, it is another design pattern :)

Patterns: Local Singleton vs. Global Singleton?

There is a pattern that I use from time to time, but I'm not quite sure what it is called. I was hoping that the SO community could help me out.
The pattern is pretty simple, and consists of two parts:
A factory method that creates objects based on the arguments passed in.
Objects created by the factory.
So far this is just a standard "factory" pattern.
The issue that I'm asking about, however, is that the parent in this case maintains a set of references to every child object that it ever creates, held within a dictionary. These references can sometimes be strong references and sometimes weak references, but it can always reference any object that it has ever created.
When receiving a request for a "new" object, the parent first searches the dictionary to see if an object with the required arguments already exists. If it does, it returns that object, if not, it returns a new object and also stores a reference to the new object within the dictionary.
This pattern prevents having duplicative objects representing the same underlying "thing". This is useful where the created objects are relatively expensive. It can also be useful where these objects perform event handling or messaging - having one object per item being represented can prevent multiple messages/events for a single underlying source.
There are probably other reasons to use this pattern, but this is where I've found this useful.
My question is: what to call this?
In a sense, each object is a singleton, at least with respect to the data it contains. Each is unique. But there are multiple instances of this class, however, so it's not at all a true singleton.
In my own personal terminology, I tend to call the parent class a "global singleton". I then call the created objects "local singletons". I sometimes also say that the created objects have "reference equality", meaning that if two variables reference the same data (the same underlying item) then the reference they each hold must be to the same exact object, hence "reference equality".
But these are my own invented terms, and I am not sure that they are good ones.
Is there standard terminology for this concept? And if not, could some naming suggestions be made?
Thanks in advance...
Update #1:
In Mark Seemans' reply, below, he gives the opinion that "The structure you describe is essentially a DI Container used as a Static Service Locator (which I consider an anti-pattern)."
While I agree that there are some similarities, and Mark's article is truly excellent, I think that this Dependency Injection Container / Static Service Locator pattern is actually a narrower implementation of the general pattern that I am describing.
In the pattern described in the article, the service (the 'Locator' class) is static, and therefore requires injection to have variability in its functionality. In the pattern I am describing, the service class need not be static at all. One could provide a static wrapper, if one wants, but being a static class is not at all required, and without a static class, dependency injection is not needed (and, in my case, not used).
In my case the 'Service' is either an interface or an abstract class, but I don't think that 'Service' and 'Client' classes are even required to be defined for the pattern I am describing. It is convenient to do so, but if all the code is internal, the Server class could simply be a 'Parent' class that controls the creation of all children via a factory method and keeps weak (or possibly strong) references to all of its children. No injection, nothing static, and not even a requirement to have defined interfaces or abstract classes.
So my pattern is really not a 'Static Service Locator' and neither is it a 'Dependency Injection Container'.
I think the pattern I'm describing is much more broad than that. So the question remains: can anyone identify the name for this approach? If not, then any ideas for what to call this are welcome!
Update #2:
Ok, it looks like Gabriel Ščerbák got it with the GoF "Flyweight" design pattern. Here are some articles on it:
Flyweight pattern (Wikipedia)
Flyweight design pattern (dofactory.com)
Flyweight Design Pattern (sourcemaking.com)
A 'flyweight factory' (server) and 'flyweight objects' (client) approach using interfaces or abstract classes is well explained in the dofactory.com article an is exactly what I was trying to explain here.
The Java example given in the Wikipedia article is the approach I take when implementing this approach internally.
The Flyweight pattern also seems to be very similar to the concept of hash consing and the Multiton pattern.
Slightly more distantly related would be an object pool, which differs in that it would tend to pre-create and/or hold on to created objects even beyond their usage to avoid the creation & setup time.
Thanks all very much, and thanks especially to Gabriel.
However, if anyone has any thoughts on what to call these child objects, I'm open to suggestions. "Internally-Mapped children"? "Recyclable objects"? All suggestions are welcome!
Update #3:
This is in reply to TrueWill, who wrote:
The reason this is an anti-pattern is because you are not using DI. Any class that consumes the Singleton factory (aka service locator) is tightly coupled to the factory's implementation. As with the new keyword, the consumer class's dependencies on the services provided by the factory are not explicit (cannot be determined from the public interface). The pain comes in when you try to unit test consumer classes in isolation and need to mock/fake/stub service implementations. Another pain point is if you need multiple caches (say one per session or thread)
Ok, so Mark, below, said that I was using DI/IoC. Mark called this an anti-pattern.
TrueWill agreed with Mark's assessment that I was using DI/IoC in his comment within Mark's reply: "A big +1. I was thinking the same thing - the OP rolled his own DI/IoC Container."
But in his comment here, TrueWill states that I am not using DI and it is for this reason that it is an anti-pattern.
This would seem to mean that this is an anti-pattern whether using DI or not...
I think there is some confusion going on, for which I should apologize. For starters, my question begins by talking about using a singleton. This alone is an anti-pattern. This succeeded in confusing the issue with respect to the pattern I am trying to achieve by implying a false requirement. A singleton parent is not required, so I apologize for that implication.
See my "Update #1" section, above, for a clarification. See also the "Update #2" section discussing the Flyweight pattern that represents the pattern that I was trying to describe.
Now, the Flyweight pattern might be an anti-pattern. I don't think that it is, but that could be discussed. But, Mark and TrueWill, I promise you that in no way am I using DI/IoC, honest, nor was I trying to imply that DI/IoC is a requirement for this pattern.
Really sorry for any confusion.
It looks like classic Flyweight design pattern from the GoF book. It does not cover the singleton factory with hash map, but generally covers saving on space and performance by reusing already created object, which is referenced by many other objects. Check out this pattern.
The objects themselves aren't following the singleton pattern, so maybe referring to the fetched objects as singleton can be confusing.
What about a Recycling Factory? :]
The structure you describe is essentially a DI Container used as a Static Service Locator (which I consider an anti-pattern).
Each of the services created by this Service Locator has a so-called Singleton lifetime. Most DI Containers support this as among several available lifetimes.

Categories