Java Generics. What benefit in my case?

2019-07-27 14:56发布

问题:

At this moment I start work on small web application based on MVC. Now I try implement main classes for Model layout using DAO pattern.

So, first of all I create two entity classes (for example): Author and Book:

package myProject.model.entity;

import java.io.Serializable;

    public class Author implements Serializable {

        private static final long serialVersionUID = 7177014660621405534L;

        private long id;
        private String firstName;
        private String lastName;

        public Author() {       
        }
    // getter and setter methods here

    }

and Book class:

  package myProject.model.entity;

    import java.io.Serializable;

        public class Book implements Serializable {

            private static final long serialVersionUID = 7177014660621405534L;

            private long id;
            private String title;
            private String description;

            public Book() {     
            }
        // getter and setter methods here

        }

On next step, I see, that classes Book and Author both have getId() and setId(). so, I create interface Persistent for my Entity classes:

 package myProject.model.entity;

        public interface Persistent {

                public long getId();
                public void setId(long id); 


        }

So, first my question:

It is correct implementation for model package?

On the next step, I start implement classes for package dao.

package myProject.model.dao;

import java.util.List;

import myProject.model.entity.Persistent;

public interface Dao {

    Persistent get(long id);

    void save(Persistent persistent);

    void delete(long id);
}

Next step: create interfaces AuthorDao and BookDao, that extend base dao interface Dao

But both interfaces: AuthorDao and BookDao - at this moment empty. What do you think - it in normal, that interfaces empty? It is my second question.

And on the last step I create package model.dao.hibernate and add to the package to class AuthorDaoHibernate and BookDaoHibernate - both class implements AuthorDao and BookDao interfaces.

And My main question now:

my interface Dao work with objects type Persistent and I dont use Generics. And all ok and nice.

What do you thinks - what benefits I have, if I re-work Dao interface wit Generics:

package myProject.model.dao;

import java.util.List;

import myProject.model.entity.Persistent;

public interface Dao<Persistent> {

    T get(long id);

    List<T> getAll();

    void save(T persistent);

    void delete(long id);
}

My Dao classes work only with persistent entities - no any other object type...

Do you really any reasons in me case use Generics?

回答1:

Generics can greatly improve code readability and reduce errors that could come from wrong casting.

We're using something similar to what you described (note that there are interfaces and implementations needed).

Here's a basic example (I'll leave the getters and setters out for brevitiy):

@MappedSuperClass
class BaseEntity {
  @Id
  private int id;
}

@Entity
class UserEnity extends BaseEntity {
  //user stuff like name
}

class BaseDAO<T extends BaseEntity> {
  public T findById(int id) { 
    ... 
  }
  //other generic CRUD methods
}

@Stateless
class UserDAO extends BaseDAO<UserEntity> {
  //additional user specific methods
}

Using UserDAO would then be like this:

 UserDAO userDao; //some injection or lookup

 //no explicit cast needed here, thanks to generics
 UserEntity user = userDao.findById(userId);

 //compiler error due to the generic parameter being UserEntity and AnotherEntity doesn't extend that
 AnotherEntity a = userDao.findById(someId);


回答2:

If you want to use generics you should define Dao as following:

public interface Dao<T extends Persistent> {
    .....................
    void save(T persistent);
    ...................
}

Now when you extend it you will have to create save that accepts Book only:

public class Book extends Dao<Book> {
    .....................
    void save(Book persistent);
    ...................
}

The benefit here is that you cannot pass Author to BookDao. This will not pass compilation.

BTW if you are using Hibernate, JPA or other ORM solution you do not really have to create DAO per entity. One generic dao can solve all your needs.



回答3:

There is no reason here. If it's unique, it's not generic, by definition ! List getAll() will do the Job.

The ArrayList is Generic because it will sometimes return Persistent, sometime President.