Spring + Mongo + Generics + Flexibility - java

The following code doesn't work (of course), because the marked line does not compile:
MyClass {
//singleton stuff
private static MyClass instance;
private MyClass () {}
public static MyClass getInstance() {
if(instance==null) {
instance = new MyClass ();
}
return instance;
}
// method creating problems
public NonGenericSuperClassOfGenericClass create(Class<?>... classes) {
if(someCondition)
return new GenericClass<classes[0],classes[1]>; // DOES NOT COMPILE
else
return new OtherGenericClass<classes[0]>;
}
}
Therefore, I actually don't know whether "create" will return
GenericClass<classes[0],classes[1]>
or
OtherGenericClass<classes[0]>
which have different numbers of parameters.
This happens because I'm using Spring and I plan to use MongoDB, but in the future I may need to switch to something different (e.g. Hibernate).
The class GenericClass is something like:
GenericClass<PersistetType1, Long>
or
GenericClass<PersistentType2, Long>
where PersistentType1/2 are classes that I need to finally store in the DB, while, GenericClass is a sort of Proxy to access Mongo APIs. In fact, it looks like:
public MongoTemplate getTemplate();
public void save(T toInsert);
public List<T> select(Query selectionQuery);
public T selectById(ID id);
public WriteResult update(Query selectionQuery, Update updatedAttributes);
public void delete(T toRemove);
public void delete(Query selectionQuery);
Now, what?
From Controllers (or Entity, if you are picky) I need to instantiate the repository and invoke any methods. This causes the Controllers to be coupled with MongoDB, i.e. they explicitly have to instantiate such GenericClass, which is actually called MongoRepository and is strictly dependent on Mongo (in fact it is a generic with exactly two "degrees of freedom").
So, I decided to create MyClass, that is a further proxy that isolates Controllers. In this way, Controller can get the single instance of MyClass and let it create a new instance of the appropriate repository. In particular, when "somecondition" is true, it means that we want to use MongoRepository (when it is false, maybe, a need to instantiate a Hibernate proxy, i.e. HibernateRepository). However, MongoRepository is generic, therefore it requires some form of instantiation, that I hoped to pass as a parameter.
Unfortunately, generics are resolved at compile time, thus they don't work for me, I guess.
How can I fix that?

In order to decouple the underlying persistence store from your application logic I would use the DAO approach.
Define the interface of your DAO with the required methods e.g. save, update etc. And then provide an implementation for each persistence provider you might need e.g.UserAccess might be the interface which you could implement as HibernateUserAccess and MongoUserAccess. In each implementation you inject the appropriate Template e.g. Mongo or Hibernate and use that to complete the persistence operation.
The issue you might have is that your load operation would return an instance of User, this would need to vary across persistence providers i.e. JPA annotations would be different to the Spring Data annotations needed for MongoDB (leaky abstraction).
I would probably solve that by creating a User interface to represent the result of the persistence operation and having an implementation for each persistence provider. Either that or return a common model which you build from the results of a JPA or Mongo load.

Related

Avoid 'downpassing' of dependencies to Entity subclasses

I have the following problem:
I have a superclass called Entity, which provides some basic methods every entity has. For this, it needs some services to run such as AbstractPotionService. This dependency is needed by none of its subclasses directly, but I would have to pass it every time I instantiate a sub-type of an Entity such as MobileEntity
public class Entity {
private AbstractPotionService potionService;
protected EntityTypeConverter converter;
public Entity(EntityTypeConverter converter, AbstractPotionService potionService) {
this.converter = converter;
this.potionService = potionService;
}
public void addEffect(EffectType effectType, int durationInSeconds) {
potionservice.applyEffectTo(this, effectType, durationInSeconds);
}
...
}
public class MobileEntity extends Entity {
public MobileEntity(EntityTypeConverter converter, AbstractPotionService potionService){
super(converter, potionService);
}
public attack(MobileEntity victim) {
...
}
...
}
This feels kind of wrong as it is a lot of tedious work and makes the project less maintainable when I want to extend the Entity class. My first thought was to use a Singleton here and get an instance of the services in the constructor of Entity directly (via static methods), but wouldn't that create a God dependency?
I also read about composition but I couldn't find an appropriate example on how to apply it in my case. Does anyone have an idea?
Chapter 4 (page 106) of Dependency Injection Principles, Practices, and Patterns (DIPP&P) (that I coauthored) states:
Entities that contain behavior besides their usual set of data members would easily get a wide range of methods, each requiring their own dependencies. Although you might be tempted to use Constructor Injection to inject such dependencies, that leads to a situation where each such entity needs to be created with all of its dependencies, even though only a few may be necessary for a given use case. This complicates testing the logic of an entity, because all dependencies need to be supplied to the constructor, even though a test might only be interested in a few dependencies. Method Injection [...] offers a better alternative.
The case of the required constructor dependencies is even exaggerated in your case, because every sub type needs to have those dependencies in their own constructor and need to pass them through to the Entity base type. If you add a new dependency to Entity it will cause all derived entities to change (and with them, all their tests), which can cause maintainability issues.
So instead, DIPP&P advises the use of Method Injection instead which, in your case, would look like this:
public class Entity {
public Entity() { } // <-- No more Constructor Injection
public void addEffect(
EffectType effectType,
int durationInSeconds,
AbstractPotionService potionService) // <-- Method Injection
{
potionservice.applyEffectTo(this, effectType, durationInSeconds);
}
...
}
With Method Injection, the method requiring the dependency is supplied with that dependency. And while the method uses the dependency, unlike Constructor Injection, it doesn't store the dependency.
This has the effect that its now the consumer's responsibility to supply the correct dependency. In most cases it would mean that the dependency is injected into the consumer using Constructor Injection.
Thank you for the answers/comments. With #Steven's answer and #Andy's comment, I was able to build a solution. As already pointed out in Steven's answer, using pure method injection every time an effect is added might not be the cleanest solution as you would have to request the dependency in any class using this method.
So I took the idea of using a factory class to create my entities. After it has checked the entity type and injected the specific data, some method injections are done at the end:
public Entity createEntity(EntityType type) {
Entity output = new Entity();
if (type == EntityType.MONSTER) {
output = new MonsterEntity(someMonsterDependency);
} else if (type == EntityType.PLAYER) {
output = new PlayerEntity(somePlayerDependencies);
} if (type == EntityType.FRIENDLY_NPC) {
...
}
output.setPotionService(potionService);
output.injectOtherDependencies...
return output;
}
So now, I only have to load the service implementations on startup, inject them into my EntityFactory, and can then create entities. If someone still has a better solution, feel free to post it.

How to inject a variable number of similar components that have dependencies themselves?

Background
I want to realize dependency injection in Python using injector (or pinject) which itself heavily borrows from guice. While an answer using Python/injector would be ideal, I'm also very happy about solutions/approaches that feature Java/guice.
Intention
I'll give you a quick summary of what I want to achieve: I have a component that depends on a list/sequence of other components that all implement the same interface. Those components have dependencies themselves which may vary amongst the different implementations. The concrete types (implementations) shall be configurable by the user (or using any mechanism of the DI framework).
Example
Yes, I've read Modules should be fast and side-effect free which suggests not to use an XML file for configuration, however as I don't know how to realize this within the framework I'll use one to demonstrate the dependency structure:
<RentingAgency>
<Vehicles>
<Car>
<DieselEngine></DieselEngine>
</Car>
<Car>
<PetrolEngine></PetrolEngine>
</Car>
<Bike></Bike>
</Vehicles>
</RentingAgency>
In this example there is a renting agency (the component that depends on a list of others) that rents out all kinds of vehicles (the interface). The specific vehicles in their fleet (in this case two cars and one bike) should be configurable but fixed during runtime. The vehicles themselves can have dependencies and they can be different depending on the type of vehicle (a car depends on a motor, a bike has no dependencies in this case).
Question
How can I construct the renting agency within the DI framework so that all required vehicles are injected and their dependencies resolved properly?
Maybe helpful
Multibinder
I've read about Multibinder (injector seems to have something similar with Binder.multibind) which allows for injecting a collection of objects that implement the same interface. However:
Can it be used to create multiple instances of the same class that need to receive different dependencies (the two cars (Class Car) in the example have different motors: Interface Motor, Class DieselEngine, class PetrolEngine)?
Using providers to accomplish that task seems to me like giving up the benefits of dependency injection: I could manually create the Car instances in the provider, passing the required Motor as argument, however because this pattern repeats further down the chain (i.e. multiple Motors of the same type are used and they also have dependencies) I want to use dependency injection for generating those objects too. But to manually use them in the provider it seems to me like I have to obtain the instances directly from the injector. The docs mention that injecting the injector is a rare case and from my understanding of dependency injection, the great benefit is that one can request a component and all dependencies are resolved by the framework automatically.
Also because I actually use Python I'm not sure if this approach is appropriate (as Python is quite flexible when it comes to dynamic code generation). Also injector.Injector.get.__doc__ mentions
Although this method is part of :class:Injector's public interface
it's meant to be used in limited set of circumstances.
For example, to create some kind of root object (application object)
of your application (note that only one get call is needed,
inside the Application class and any of its dependencies
:func:inject can and should be used):
Dependency injection frameworks are primarily for dependencies and because your Vehicles object is configured by the user at runtime it is more like application data than a dependency. It probably can't just be injected in one shot using MultiBinding unless you know it at compile time.
Likewise, you are right in saying that it would not be a good approach to construct your set of components by iterating and calling injector.getInstance(Bike.class) etc. For one, this is not good for testing.
However, because the objects contained in Vehicles have their own dependencies you can leverage the DI framework in the creation of your Vehicles object. Remember, also, that although you cannot bind a Provider to an implementation, when you bind a key Guice will inject that provider for you.
For the simple example in the post, consider creating a VehicleFactory. Inside, you could have something like the following:
public class VehicleModule implements Module {
#Override
public void configure(Binder binder) {
binder.bind(DieselEngine.class).toProvider(DieselEngineProvider.class);
binder.bind(PetrolEngine.class).toProvider(PetrolEngineProvider.class);
binder.bind(Bike.class).toProvider(BikeProvider.class);
}
}
public class DieselEngineProvider implements Provider<DieselEngine> {
#Inject
public DieselEngineProvider() {
//if DieselEngine has any dependencies, they can be injected in the constructor
//stored in a field in the class and used in the below get() method
}
#Override
public DieselEngine get() {
return new DieselEngine();
}
}
public class VehicleFactory {
private final CarFactory carFactory;
private final Provider<Bike> bikeProvider;
#Inject
public VehicleFactory(CarFactory carFactory, Provider<Bike> bikeProvider) {
this.carFactory = carFactory;
this.bikeProvider = bikeProvider;
}
public Bike createBike() {
return bikeProvider.get();
}
public Car createDieselCar() {
return carFactory.createDieselCar();
}
public Car createPetrolCar() {
return carFactory.createPetrolCar();
}
}
public class CarFactory {
private final Provider<DieselEngine> dieselEngineProvider;
private final Provider<PetrolEngine> petrolEngineProvider;
#Inject
public CarFactory(Provider<DieselEngine> dieselEngineProvider, Provider<PetrolEngine> petrolEngineProvider) {
this.dieselEngineProvider = dieselEngineProvider;
this.petrolEngineProvider = petrolEngineProvider;
}
public Car createDieselCar() {
return new Car(dieselEngineProvider.get());
}
public Car createPetrolCar() {
return new Car(petrolEngineProvider.get());
}
}
As you mention, there is the danger of this becoming 'factories all the way down', but Guice can help you here.
If the production of Engine becomes more complicated and involves a combination of different parameters, you can use tools like AssistedInject to auto-create the factories for you.
If you end up with a set of common dependencies and uncommon dependencies that you want to use to create different 'flavours' of an object then you have what is known as the robot legs problem then Guice can solve it using private modules.
Do note the following caveat from the Dagger 2 user guide:
Note: Injecting Provider has the possibility of creating confusing
code, and may be a design smell of mis-scoped or mis-structured
objects in your graph. Often you will want to use a factory or a
Lazy or re-organize the lifetimes and structure of your code to be
able to just inject a T.
If you follow this advice, it would seem that you would have to carefully balance using providers and using factories to create your Vehicle.

Guice 3 - Automatically building object graph when using assisted inject

Im interested what is the proper manner to construct object with dependencies which themselves have #Assisted params. An example will better illustrate:
Ordinarilly with dependencies that do not have #Assisted params you can simply have a complex heirarchy of objects which all have their dependencies and these get injected no problem, I can just get an instance of an object and all its dependencies will be generated and injected without me having to do anything.
But if I wanted to change it so some of the dependencies in the object hierarchy have #Assisted params then I have to create those instances myself using a factory ie:
public SomeConcreteService(#Assisted String string) {
this.string = string;
}
MyFactory myFactory = injector.getInstance(MyFactory .class);
SomeService myService = factory.getMyService("some string");
This would cause problems for the clean instantiation of the objects because I would have to manually create those instances. and pass them into the required object, which essentially renders the DI for that object redundant I think???? ie I would then need to use the new keyword and pass in all dependencies manually...
new MyComplexObject(myService, myOtherService)
How do I make it so that I don't have to manually build the object graph if one or more of the dependencies uses #Assisted parameters?
The question you need to ask yourself is, "why am I making this #Assisted, and who is going to create these objects?"
If you use the key to get an instance you need, then what you have is fine:
public class YourInjectableClass {
#Inject private MyFactory factory;
public void doStuff(String key) {
// You have a key, and your factory, so you can create the instance yourself.
SomeService service = factory.getMyService(key);
// [...]
}
}
But if you use the key to get an instance create an instance to create an instance to get what you need, then that seems problematic. That might be a better problem for child injectors:
public class YourInjectableClass {
#Inject private Injector injector;
public void doStuff(String key) {
// You need an OuterObject. So rather than calling
// new OuterObject(new InnerObject(factory.getMyService(key))), do:
OuterObject outerObject =
injector.createChildInjector(new OuterObjectModule(key))
.getInstance(OuterObject.class);
// [...]
}
}
Because your value is needed throughout the dependency tree, you can treat it as an injected dependency. This can be a little more confusing, but saves you from letting your dependencies care about instantiation details all the way down the line.
Alternatively, you can create a manual OuterObjectFactory facade which does manually call new. This may be a better solution for legacy code, but can help to follow the Single Responsibility Principle by ensuring that one class is responsible for abstracting away instantiation details.
N.B. I'm assuming that SomeConcreteService takes other dependencies that the object graph can provide. If not, then there's no reason to use injection at all: Give SomeConcreteService a public constructor and call new SomeConcreteService("your value here") where needed. Though Guice takes some pains to abstract away the use of new, it is also unnecessary to create data objects or dependency-light objects like HashMap or Date.

How to organize Java Business object classes

I am writing a web service and one of the operation in service is getShortURL(String longURL). In this method I first check whether longURL exists in database, if yes, return it otherwise create a shortURL, insert it in database and return to client.
My confusion is how to organize and name my classes. Apart from the web service class, right now I have 3 classes:
URLData: It just has URL attributes and getters and setters.
MongoDB: It connects to database(right now connection attributes are hard-coded in it), inserts in database, and retrieves raw string from database.
MongoDBUtil: This class has again insert(URLData) method, it calls MongoDB.insert() to insert into database. Also has retrieveURLData which in turn calls MongoDB equivalent method to do the actual job.
Web service method sets URLData setters and calls MongoDBUtil.retrieve or insert.
I am thinking that URLData class should be named URLDataBusinessObject and along with setters and getters it can have insert, update and delete methods.
MongoDBUtil can be renamed to UrlDAO and it can have different kinds of retrieve methods.
MongoDB is more kinda Select query class, not sure how to design and name it.
Please advise
URLData is fine. Don't bloat your class name with long irrelevant words. If you want to make clear that this is a business object, create a package like com.yourcompany.yourproject.bo for example, then put your URLData class in there.
Yes, UrlDAO is more specific than MongoDBUtil. You can create a com.yourcompany.yourproject.dao package for it.
Looks fine for me. However if you use some kind of framework (e.g. Spring) you don't have to create your own class to hold the database connection configurations.
I suggest you google for some tutorial on the topic, you will learn both how to use the technology and how to name/orginize your classes.
This question might be suited more for http://programmers.stackexchange.com.
Nevertheless: yes, I would change the naming.
1) URLDataBusinessObject No, never. You're adding 14 characters to a classname without adding any value. URLData was just fine.
2) You should change the naming of your DAO classes to be non-DB specific, unless you explicitly have an architecture aiming at multiple databases and the DB-specific classes perform DB-specific tasks.
I'm assuming this isn't the case and thus you should give it a more general name.
Persistence can be just fine, DAO as well, anything that shows the intended usage without going into specifics is eligible.
3) MongoDBUtil is your interface to the persistence layer, it's not a utility class in heart and soul. What's the purpose of this class? If all you do is chain the method call to MongoDB you might as well drop it and go straight to the latter.
To create a simple layered design build interfaces for all the persistence specific operations and interfaces for all the domain objects. Then code against those rather than their concrete implementations. That way it's easy to swap out a mongo persistence layer for a different one, functionality is organised so that others can easily understand it and can also test against interfaces rather than concrete implementations. You'd have something like:
URLData interface
URLDataDTO class (used in the business layer)
Persistence interface
MongoPersistence class (used in the persistence layer)
My current project does something similar and also works with Mongo. The persistence layer interface has methods like "void put(URLData)". When called the Mongo implementation constructs a new MongoURLData from the URLData passed in, extracts the DBObject then persists it. Methods like "URLData get(String id);" work the other way around. The Mongolayer queries the database and creates new URLDataDTO objects from Mongo DBObjects. The web service is then responsible for serialising/deserialising DTO objects that are sent to or received from client applications.
My Mongo Domain objects all inherit from something this:
public abstract class MongoDO<T extends Object> {
DBObject dbobject = null;
public MongoDO(T dto) {
this.dbobject = new BasicDBObject();
};
public MongoDO(DBObject obj) {
this.setDBObject(obj);
};
public abstract T toDTO() throws StorageException;
public DBObject getDBObject() {
return dbobject;
}
public void setDBObject(DBObject obj) {
this.dbobject = obj;
}
public ObjectId getIdObject() {
return (ObjectId) this.getDBObject().get("_id");
}
public void setIdObject(ObjectId id) {
this.getDBObject().put("_id", id);
}
protected String getField(String field) {
if (dbobject.containsField(field) && dbobject.get(field) !=null) {
return dbobject.get(field).toString();
} else
return null;
}
protected void setField(String field, String value) {
dbobject.put(field, value);
}
}
An example Mongo implementation would be:
public class MongoURLData extends MongoDO<URLData> implements URLData {
private static final String FIELD_SHORT_URL = "surl";
public String getShortUrl() {
return getField(FIELD_SHORT_URL);
}
public void setShortUrl(String shortUrl) {
setField(FIELD_SHORT_URL, shortUrl);
}
public URLData toDTO(){
URLDataDTO dto = new URLDataDTO();
dto.setShortURL(getShortURL);
return dto;
}
}

How to distinguish between instances of class?

I have class Validator, which manage all validation criteria from files and database. But this criteria are loaded by Loader like this:
Validator validator = Loader.load("clients"); //get all from clients.cfg file
What is the best approach to determine from another class, which criteria are currently loaded?
Importer importer;
Validator clientsValidator = Loader.load("clients");
Validator addressValidator = Loader.load("address"); ...
importer.validate(data, clientsValidator, addressValidator);
public class Importer{
public void validate(Data data, Validator... validator){
...
validateClient(data, one of validators);
validateAddress(data, another of validator);
...
}
}
I need to know in Importer class, which Validator is for Clients, which for Addresses... Any good approaches?
The best way would be for you to be add a field and accompanying method to Validator to return the identifier (e.g. "clients") with which it was created.
Alternatively, if by using a different identifier when calling Loader.load() you get back instances of different classes implementing the Validator interface, then you can use the Object.getClass() method to tell those classes apart. If those classes are within a pretty small set you might even get away with using instanceof directly.
We would need more information, such as what Loader does exactly, what Validator is and how much you are allowed to change their code before being able to provide a more concrete answer.
EDIT:
Quite honestly, perhaps you should reconsider a redesign of your data model. As it stands, you can apparently mix clients and addresses without any checks. You should restructure your code to be able to rely on the type safety features of Java.
One way would be to have a generic class/interface Validator<T>, where T would the class of the validated objects:
public interface Validator<T> {
public boolean validate(T object);
}
You could then have specific Data subclasses for your data, such as Address or Client, and set typed Validator objects to Importer through specific methods:
public class Importer {
public void addAddressValidator(Validator<Address> validator) {
...
}
public void addClientValidator(Validator<Client> validator) {
...
}
}
This is far safer than mixing all validator objects in a single variadic method call, and it is also the preferred approach of most common frameworks in the wild.
Why not have a getSource() in Validator which gets set when Loader loads the source.
Thinking more about the specific question below :
I need to know in Importer class, which Validator is for Clients,
which for Addresses... Any good approaches?
Actually a better way to do this is if Loader can return a ClientValidator (implementation of Validator) for client and AddressValidator for addresses.
That way you can avoid the if-else conditions and directly call validate on the Validator class
Pass the validators by position. You must also check if the specific validator is null or not before you use.
public void validate(Data data,
Validator clientsValidator,
Validator addressValidator) {
...
if (clientsValidator != null) {
validateClient(data, clientsValidator);
}
if (addressValidator != null) {
validateAddress(data, addressValidator);
}
...
}

Categories

Resources