Interface too general - java

In the Java code I'm working with we have an interface to define our Data Access Objects(DAO). Most of the methods take a parameter of a Data Transfer Object (DTO). The problem occurs when an implementation of the DAO needs to refer to a specific type of DTO. The method then needs to do a (to me completely unnecessary cast of the DTO to SpecificDTO. Not only that but the compiler can't enforce any type of type checking for specific implementations of the DAO which should only take as parameters their specifc types of DTOs.
My question is: how do I fix this in the smallest possible manner?

You could use generics:
DAO<SpecificDTO> dao = new SpecificDAO();
dao.save(new SpecificDTO());
etc.
Your DAO class would look like:
interface DAO<T extends DTO> {
void save(T);
}
class SpecificDAO implements DAO<SpecificDTO> {
void save(SpecificDTO) {
// implementation.
}
// etc.
}
SpecificDTO would extend or implement DTO.

Refactoring to generics is no small amount of pain (even though it's most likely worth it).
This will be especially horrendous if code uses your DTO interface like so:
DTO user = userDAO.getById(45);
((UserDTO)user).setEmail(newEmail)
userDAO.update(user);
I've seen this done (in much more subtle ways).
You could do this:
public DeprecatedDAO implements DAO
{
public void save(DTO dto)
{
logger.warn("Use type-specific calls from now on", new Exception());
}
}
public UserDAO extends DeprecatedDAO
{
#Deprecated
public void save(DTO dto)
{
super.save(dto);
save((UserDTO)dto);
}
public void save(UserDTO dto)
{
// do whatever you do to save the object
}
}
This is not a great solution, but might be easier to implement; your legacy code should still work, but it will produce warnings and stack traces to help you hunt them down, and you have a type-safe implementation as well.

Related

Java generics in List return type on a method inherited from multiple interfaces

I'm currently working at a company that has a diverse set of modules. In that company if you want to provide module internals you provide it via a java interface, that hides the actual implementing type and gives an interface for the requesting module. Now I want to have one provider to be able to provide data for multiple modules that expose different fields or methods of the actual internal data.
Therefore I have an internal Object, which has some data and I have an interface for each module that needs access to some but not strictly all fields. Finally I have an external object that implements all those interfaces and holds an instance of the internal object to delegate the method calls:
public class InternalObject {
public int getA() { return 0; }
public int getB() { return 0; }
}
public interface ModuleXObject {
int getA();
}
public interface ModuleYObject {
int getA();
int getB();
}
public class ExternalObject implements ModuleXObject, ModuleYObject {
private InternalObject _internal;
public int getA() { return _internal.getA(); }
public int getB() { return _internal.getB(); }
}
Now that is all fine and dandy, but if I want to provide - lets say - repository methods for finding a list of said objects typed for the correct module, I run into problems with how I can achieve that. I would wish for something like the following:
public interface ModuleXObjectRepository {
List<ModuleXObject> loadAllObjects();
}
public interface ModuleYObjectRepository {
List<ModuleYObject> loadAllObjects();
}
public class ExternalObjectRepository implements ModuleXObjectRepository, ModuleYObjectRepository {
public List<ExternalObject> loadAllObjects() {
// ...
}
}
This doesn't compile saying the return type is incompatible.
So my question is, if it is possible to achieve something like that and if, how?
I should note that I tried some different approaches which I want to include for completeness and to portray their downsides (in my eyes).
Approach 1:
public interface ModuleXObjectRepository {
List<? extends ModuleXObject> loadAllObjects();
}
public interface ModuleYObjectRepository {
List<? extends ModuleYObject> loadAllObjects();
}
public class ExternalObjectRepository implements ModuleXObjectRepository, ModuleYObjectRepository {
public List<ExternalObject> loadAllObjects() {
// ...
}
}
This approach is quite close to the solution I would prefer, but results in code like this:
List<? extends ModuleXObject> objects = repository.loadAllObjects();
Therefore requiring the user to include the "? extends" into each List-Declaration regarding to an invocation of loadAllObjects().
Approach 2:
public interface ModuleXObjectRepository {
List<ModuleXObject> loadAllObjects();
}
public interface ModuleYObjectRepository {
List<ModuleYObject> loadAllObjects();
}
public class ExternalObjectRepository implements ModuleXObjectRepository, ModuleYObjectRepository {
public List loadAllObjects() {
// ...
}
}
This approach just omits the generic in the ExternalObjectRepository and therefore reduces the type safety too much in my opinion. Also I haven't tested if this actually works.
Just to reharse, is there any possible way to define the loadAllObjects-method in a way that enables users to get lists that are typed with the objects for their respective module without
requiring "? extends" in the users code
degrading type safety in the repository implementation
using class/interface level generics
The challenge with allowing it to be typed as List<ModuleXObject> is that other code may hold is as a List<ExternalObject>.
All ExternalObject instances are ModuleXObject instances but the inverse is not true.
Consider the following additional class:
public class MonkeyWrench implements ModuleXObject{
//STUFF
}
MonkeyWrench instances are NOT ExternalObject instances but if one could cast a List<ExternalObject> to a List<ModuleXObject> one could add MonkeyWrench instances to this collection, and this causes a risk of run time class cast exceptions and ruins type safety.
Other code could very easily have:
for(ExternalObject externalObject:externalObjectRepository.loadAllObjects())
If one of those instances is a MonkeyWrench instance, run time class cast, which is what generics are meant to avoid.
The implication of ? extends ModuleXObject is that you can read any object from the collection as a ModuleXObject but you can't add anything to the collection as other code may have additional constraints on the collection that are not obvious/available at compile time.
I'd suggest in your case to use ? extends ModuleXObject as its semantics seem to align with what you want, namely pulling out ModuleXObject instances, e.g.
ModuleXObjectRepository repo = //get repo however
for(ModuleXObject obj : repo.loadAllObjects()){
//do stuff with obj
}

Code repetition vs readablility

I have multiple services (in Spring MVC) that are children of a global Service. So I need to know about the best practice (or your opinions) with multiple methods with this example:
//Domain classes
public class MyParentObject{}
public class MyObj extends MyParentObject{}
//Services
public class MyParentObjectServiceImpl implements MyParentObjectService{
#Override
public MyParentObject findObjectByProp(String prop, String objectType){
//myCode (not abstract class)
}
}
public class MyObjServiceImpl extends MyParentObjectServiceImpl implements MyObjectService{
private myObjType = "MyObj";
#Override
public MyObj findMyObjByProp(String prop){
return (MyObj) super.findObjectByProp(prop, this.myObjType);
}
}
And in this approach, I use calls like this:
MyObj foo = myObjService.findMyObjByProp(prop);
So I need to know if this approach is "better" or more apropiate that calling directly the parent method with the second parameter. E.g:
MyObj foo = (MyObj)myParentObjectService.findObjectByProp(prop, "MyObj");
..and avoiding the creation of second methods, more specific. It is important to know that the children services will be created anyway, because we have lot of code that is specific of a domain objects.
I have the idea that the first approach is better, because is more readable, but I need to support that decision with some documents, blog, or opinions to discuss this designs with my colleagues.
This looks like a tagged class hierarchy. It's difficult to comment on the value of this design in general without knowing the details. However, a slightly different approach that I would recommend is to generify your base class to gain a little bit of type safety.
In particular:
public /* abstract */ class MyParentObjectServiceImpl<T extends MyParentObject>
implements MyParentObjectService{
MyParentObjectServiceImpl(Class<T> type) { this.type = type; }
private final Class<T> type; // subclasses provide this
#Override
public T findObjectByProp(String prop){
//you can use type for object specific stuff
}
}
public class MyObjServiceImpl extends MyParentObjectServiceImpl<MyObj>
// You might not need this interface anymore
// if the only method defined is findMyObjByProp
/* implements MyObjectService */ {
MyObjServiceImpl() {
super(MyObj.class);
}
#Override
public /* final */ MyObj findMyObjByProp(String prop) {
return (MyObj) super.findObjectByProp(prop, this.myObjType);
}
}
You definitely gain in type safety (casting will only appear in the base class), you get rid of the "tags" (the strings that identify the different objects) and possibly reduce the number of classes/interfaces required to implement the whole hierarchy. I successfully used this approach several times. Note that this works best if the base class is abstract. Food for thoughts.

Type safe tunneling of user data between method calls

I am developing an API allowing users to transfer data using a certain protocol. Throughout the communication, two events - EventA and EventB occur. B is optional, but strongly related to A. They occur in the sequence (AB?)*. This events are exposed to the user as a hook call to an interface:
interface IEventHandler {
void eventAOccured(EventAData aData);
void eventBOccured(EventBData bData);
}
Now I want the user to be able to pass some data about event A to the hook of event B while keeping the interface stateless. First I thought something like
interface IEventHandler<U> {
U eventAOccured(EventAData aData);
void eventBOccured(EventBData bData, U userData);
}
Unfortunately, as generics do not offer runtime information (not without reflection, at least) the API has no way to call eventBOccured, as the type of its second parameter is not known at compile time. Introducing a markerinterface and U extends IMarker solves this, but does not spare the upcast I wanted to avoid. IMHO if I would go with the upcast I could simply pass Object and get the same thing.
I am pretty sure (Java) generics are the wrong tool here. Am I missing something? How would you tackle the problem?
I will do that way :
package com.stackoverflow.user3590895.questions24098455;
//-------------------------------
package com.stackoverflow.user3590895.questions24098455;
public class EventData implements IEventData{
//default is type A
private int type=IEventData.TYPE_A;
#Override
public int getType() {
System.out.print("Event [type:"+type+"]!");
return type;
}
}
//-------------------------------
package com.stackoverflow.user3590895.questions24098455;
public interface IEventData {
public static char TYPE_A='A';
public static char TYPE_B='B';
public int getType();
}
//-------------------------------
package com.stackoverflow.user3590895.questions24098455;
public interface IEventHandler<U> {
U eventOccured(IEventData data);
}
Use case:
- make a call of event (with event of you choice
- api catch event and can know his type by calling function getType.
- if you are an eventData B, you can herit of EventData and make a new EventData for B Type. You can add some specific function for EventDataB, and specific datas also.
give me feedback.
If I correctly understand, you could use a wrapper around you data containing its class definition. Something like
class Wrapper<U extends IMarker> {
U data;
Class<U> clazz;
// constructor, getters and setters omitted
}
Your event interface would be
interface IEventHandler<U extends IMarker> {
Wrapper<U> eventAOccured(EventAData aData);
void eventBOccured(EventBData, Wrapper<U> user data);
}
That way, Wrapper class is known, and API can call it without problem. And in eventBOccured you have the right type for your upcast.

How do Generics and Fields assist DAO Pattern in Standalone Java applications

//Interface DAO
public abstract class BaseDAO<T extends BaseDTO> {
public void update(T t) throws DBException {
Field[] fieldsToInsert = t.getClass().getDeclaredFields();
//code to update database object academic or event
}
public Integer create(T t) throws DBException {
Field[] fieldsToInsert = t.getClass().getDeclaredFields();
//code to create academic or event in database
}
}
//Concrete DAOs
public class AcademicDAO extends BaseDAO<AcademicDTO> {
//provide implementation
}
public class EventDAO extends BaseDAO<EventDTO> {
//provide implementation
}
//Transfer object
public class AcademicDTO extends BaseDTO {
String title;
String surname;
//getters and setters
}
public class BaseDTO {
protected Integer ID;
public Integer getID() {
return ID;
}
public void setID(Integer ID) {
this.ID = ID;
}
}
Hello Guys, I have a sample code on me that follows the above structure to create a small java application to manage academics and events. It is leniently following this pattern
1- You experts are familiar with this pattern more than me. I would like to understand why generics are used in this case so DAOs can extend and implement a generic base class. It would be great if one can show how generics here may be advantageous using an example.
2 - I have also witnessed the use of java Fields. Is there a link between generics and Fields?
I would like to document DAO pattern in an academic report, but I am finding difficult to understand how Generics and Reflect Field play a part here. Do they support flexibility and loose coupling?
The code you've provided is reusable set of logic to load and persist entities. Many times, in an application of non-trivial size, you'll wind up persisting many different types of objects. In this example, you can define as many objects as necessary, but only define the logic to actually save and load once. By asking the DTO what Field objects are there, it can get at the data to help construct queries for loading and saving.
Generics allow you to use this pattern while maintaining type safety. AcademicDAO can only handle AcadmeicDTO. You can't use AcademicDAO to store EventDTO. Generics allow the instance of the class to rely on a more specific type when dealing with the Field objects. If you didn't have generics, the BaseDAO would take Object, and you wouldn't be able to access any methods except those that Object provides because the JVM wouldn't know what class is provided, so it has to limit it's knowledge to that of Object. Using getClass().getDeclaredFields() bypasses that limitation because getClass() returns the actual class of the Object parameter.
Field is just a way to use reflection to access the values of the properties in each DTO. If you had to access the fields directly, with getTitle(), you couldn't reuse a generic base class to do your persistence. What would happen when you needed to access EventDTO? You would have to provide logic for that. Field allows you to skip that logic.
Edit:
To explain what I mean by accessing getID, you could do the following within BaseDAO because T is known to be a BaseDTO with a getID() method defined:
public abstract class BaseDAO<T extends BaseDTO> {
public boolean update(T t) throws DBException {
Integer id = t.getID();
Field[] fields = t.getClass().getDeclaredFields();
// Assuming you have a db object to execute queries using bind variables:
boolean success = db.execute("UPDATE table SET ... WHERE id = ?", id.intValue());
return success;
}
}
If you had this instead (in a non-generic class):
public boolean update(Object o) throws DBException {
// This line doesn't work, since Object doesn't have a getID() method.
Integer id = t.getID();
Field[] fields = o.getClass().getDeclaredFields();
boolean success = db.execute("UPDATE table SET ... WHERE id = ?", id.intValue());
return success;
}
You'd have to look through those Field objects, or ask for the ID field and assume it existed.
For question 1. The use of generics allows the same implementations of update and create to be used regardless of the type of the DTO. Consider if you didn't use generics. Then the best you could do for the parameter type of update would be BaseDTO, but then you could call
academicDAO.update( eventDTO )
which doesn't make sense. With the code as you have it, this would be a type error. So the main advantage is: better type checking.
For question 2. The use of Fields allows a single implementation of update and create to work on DTO object of various concrete types.

Is my DAO strategy ok?

I'm using Hibernate. The question is at the bottom.
The current strategy
It's simple.
First of all, I have a basic Dao<T>.
public class Dao<T> {
private Class<T> persistentClass;
private Session session;
public Dao(Class<T> persistentClass) {
this.persistenClass = persistentClass;
this.session = HibernateUtil.getCurrentSession();
}
It's nice as a base class and it passes the most common methods up to its Session.
public T get(Serializable id) {
#SuppressWarnings("unchecked")
T t = (T) this.session.get(this.persistentClass, id);
return t;
}
protected Criteria getCriteria() {
return this.session.createCriteria(this.persistentClass);
}
When there's need to use queries on the model, it goes into a specific DAO for that piece of model, which inherits from Dao<T>.
public class DaoTask extends Dao<Task> {
public DaoTask() {
super(Task.class);
}
public List<Task> searchActiveTasks() {
#SuppressWarnings("unchecked")
List<Task> list = (List<Task>) this.getCriteria()
.add(Restrictions.eq("active", true))
.list();
return list;
}
}
This approach has always worked well.
However...
However, today I found that many times an instance needs reattachment to the Session and a line similar to the following ends up happening:
new Dao<Book>(Book.class).update(book);
... which I find to be bad, because
I don't like specifying the redundant Book.class
If ever a DaoBook arises, this construct will become obsolete.
So I turned Dao<T> into an abstract class, and went on to refactor the old code.
Question
In order to remove the Dao<T> references from the codebase, I thought of two approaches:
Create specific DAOs for every class that ever needs attachment, which would generate many almost empty DaoBooks and the sort.
Create a class that owns a Dao<Object> and exposes only the attachment methods (i.e. save(), update() etc).
I'm tending to go with #2, but I thought this "AttacherDao" pattern might be bad, so I'd like your opinion.
Any cons for #2? Also, do you find anything wrong with "the current strategy"?
Our approach is to have a DAO object (derived from a commonDao) for each persistent class. In fact we define interface for this DAO class and each DAO decides which interfaces are opened up.
Using the following code, user cannot delete the PersistentClass.
interface PersistentClassDao {
void save(PersistentClass persistentObject);
}
Class PersistentClassDaoImpl extends CommonDao implements PersistentClassDao {
void save(persistentObject) {
persist(persistentObject);
}
Even though it has some additional overhead, this approach helps in unit testing appropriate code before exposing an interface.
We've chosen an approach similar to lud0h's, with the following twist:
abstract class<T extends IModelObject> JdbcCrudDao<T>{
void create(T dbo){}
T findByFoo(String foo){}
void update(T dbo){}
void delete(T dbo){}
}
class BarDao extends JdbcCrudDao<Bar>{
}
But, the twist is that we selectively expose methods on the Dao through a facade and forward only those we absolutely must.
class BarController implements IController{
private static final BarDao dao;
// ...
void update( IBar bar ){
dao.update(bar);
}
}
The only short-coming in all this is it requires some casting about if you wish to hide your database keys behind an interface type (which we do), but it's a pretty minor inconvenience versus the alternative (database code outside of the Daos).
Couple of questions
Are you frequently creating your DAO to do a single task or are these long lived?
What about using a static function? Clearly your Book object can be bind the DAO function to without the Book.class reference...
Otherwise, I'm a little worried about keeping the session object around instead of fetching whatever the current session is - isn't it considered "bad" to have long lived session objects? I'm not a master of DAO, so maybe I'm missing something here.

Categories