I've been reading a bit about the Cake Pattern in Scala (I know that is old stuff), and I cannot see or imagine an way to lock down the concrete classes, so dependencies don't leak from the classes where they are injected.
A simple and current example comes from the play-reactive-mongo-db activator template. In that app, the controllers use the ReactiveMongoComponents trait to get an instance of the driver ReactiveMongoApi.
Now, the problem is that the controller inherits has a public method to return an instance of reactiveMongoApi and as such breaking 2 fundamental principles: Encapsulation and Information Hiding. I know the example is not great (as a controller shouldn't access any data store), but the same applies if there would be domain services or repositories. I know that those classes (domain services, repositories, etc) would have a trait that defines the accessible methods, and there wouldn't be a public method/attribute to get the dependency, but the concrete implementation does leak.
TL;DR: Cake pattern leaks dependencies from concrete implementations, how can this be avoided?
Related
I would like to write test for a controller class. The controller class takes a service object as constructor parameter. Added the #Inject annotation to the constructor of the service class.
class AssociateService #Inject()(configuration: Configuation){...}
The constructor parameter of the service class is a custom configuration object also created for the application. I added the #Inject to the constructor of the config class as well. Now I'm getting these types of error messages:
No implementation for "className" was bound.
Could not find a suitable constructor in java.lang.Integer. Classes must have either one (and only one) constructor annotated with #Inject or a zero-argument constructor that is not private.
The configuration class has several constructor parameters, those are "basic" types (Int, Boolean) and one parameter is a custom class type (className).
How should I do this binding or is it just enough to annotate something else?
And why it says that constructor error message?
As far as I know, there are two ways with tests and guice, with trade offs:
Don't using field injections, using only constructor injections and fields assignment in constructor for injected parameters. This approach enables very simple solution for testing, just don't use dependency injection in tests. But all your classes must have ability to be created with new operator in test cases...
Ps. You can define optional constructor and use field injections, of course, but it is not very clear solution.
Creating correct module with injectable interfaces binding to its implementations for every test or group of similar tests. Sometimes this approach takes a lot of unnecessary working hours.
You must design your software to maintain testability. Sometimes not every line of code in project need to be tested, sometimes not every code is testable, you must separate it from important parts of your software, that requires testing. If you design your software with single responsibility principe so writing tests is much easer...
When using Dagger 2, very often I'm applying the following pattern:
Create interface, let's call it LoginService
Create the only one implementation - LoginServiceImpl with the constructor injection:
class LoginServiceImpl implements LoginService {
#Inject LoginServiceImpl() {}
}
Bind the implementation to the interface:
#Binds
abstract LoginService bindStatisticsService(LoginServiceImpl impl);
Always depend on the interface - LoginService in this case.
Is there a possibility to avoid the #Binds annotated method? Is there a simpler (with the less amount of boilerplate code) way to tell Dagger - this class is the only one implementation of the interface, always bind it for example in some annotation on the interface itself?
I've read the documentation and unfortunately haven't found anything like that, but maybe someone knows some trick which can solve my problem.
I don't think that's possible, even hypothetically.
Dagger can't really tell that there's only one implementation, and the only way it could would be to search for every class on the (compilation) classpath to try to find all sorts of possible implementation. That would be slow at best, but Java allows classloading from custom classloaders, so you aren't ever really guaranteed to get a full list of available classes. Even if you were to claim that Dagger should just match against the first appropriate assignable type it sees (because you know that there's only one), Dagger may not have a way to identify where to find that implementation type.
Ultimately it's going to be difficult to improve on a single-line #Binds statement that identifies the fully-qualified class of the binding key (your.package.name.LoginService) and target (your.package.name.LoginServiceImpl).
I have a single concrete class: Validator that does a single thing.
I have no need to create an interface as there is only a single implementation of this.
Does this fail dependency of inversion principle when injecting instances of Validator into higher level classes?
If i am to use an interface for this class it causes a naming problem
We use interfaces because they help for swapping implementations, mocking during unit testing and of course abstraction.
Does this fail dependency of inversion principle when injecting
instances of Validator into higher level classes?
According to DIP, Validator should implement IValidator and classes needing it should just know about IValidator contract, not Validator definition itself. However, IOC containers (ex. Unity) allow you to register class types instead of interface.
It's just a principle and there could be valid exception to not follow it as-is. In cases like you, I would focus more on the core intention of DIP, IOC and DI; and that is to have loosely coupled code. I would hesitate to create interface if I am sure there's going to be just one implementation.
I would just make sure that nothing except my IOC container instantiates Validator.
I've written a Scala trait, named Cache[A,B], to provide a caching API. The Cache has the following methods, asyncGet(), asyncPut(), asyncPutIfAbsent(), asyncRemove().
I'm going to have a few static methods, such as getOrElseUpdate(key: A)(op: => B). I don't want methods like this as abstract defs in the Cache trait because I don't want each Cache implementation to have to provide an implementation for it, when it can be written once using the async*() methods.
In looking at Google Guava and parts of the Java library, they place public static functions in a class that is the plural of the interface name, so "Caches" would be the name I would use.
I like this naming scheme actually, even though I could use a Cache companion object. In looking at much of my code, many of my companion objects contain private val's or def's, so users of my API then need to look through the companion object to see what they can use from there, or anything for that matter.
By having a object named "Caches" is consistent with Java and also makes it clear that there's only public functions in there. I'm leaning towards using "object Caches" instead of "object Cache".
So what do people think?
Scala's traits are not just a different name for Java's interfaces. They may have concrete (implemented) members, both values (val and var) and methods. So if there's a unified / generalized / shared implementation of a method, it can be placed in a trait and need not be replicated or factored into a separate class.
I think the mistake starts with "going to have a few static methods". Why have static methods? If you explain why you need static methods, it will help figure out what the design should be.
Similar question but not quite the same thing
I was thinking that with extension methods in the same namespace as the interface you could get a similar effect to multiple inheritance in that you don't need to have duplicate code implementing the same interface the same way in 10 different classes.
What are some of the downsides of doing this? I think the pros are pretty obvious, it's the cons that usually come back to bite you later on.
One of the cons I see is that the extension methods can't be virtual, so you need to be sure that you actually do want them implemented the same way for every instance.
The problem that I see with building interface capability via extension methods is that you are no longer actually implementing the interface and so can't use the object as the interface type.
Say I have a method that takes an object of type IBar. If I implement the IBar interface on class Foo via extension methods, then Foo doesn't derive from IBar and can't be used interchangeably with it (Liskov Substitution principle). Sure, I get the behavior that I want added to Foo, but I lose the most important aspect of creating interfaces in the first place -- being able to define an abstract contract that can be implemented in a variety of ways by various classes so that dependent classes need not know about concrete implementations.
If I needed multiple inheritance (and so far I've lived without it) badly enough, I think I'd use composition instead to minimize the amount of code duplication.
A decent way to think about this is that instance methods are something done by the object, while extension methods are something done to the object. I am fairly certain the Framework Design Guidelines say you should implement an instance method whenever possible.
An interface declares "I care about using this functionality, but not how it is accomplished." That leaves implementers the freedom to choose the how. It decouples the intent, a public API, from the mechanism, a class with concrete code.
As this is the main benefit of interfaces, implementing them entirely as extension methods seems to defeat their purpose. Even IEnumerable<T> has an instance method.
Edit: Also, objects are meant to act on the data they contain. Extension methods can only see an object's public API (as they are just static methods); you would have to expose all of an object's state to make it work (an OO no-no).