简体   繁体   English

Java泛型。 对我来说有什么好处?

[英]Java Generics. What benefit in my case?

At this moment I start work on small web application based on MVC. 现在,我开始研究基于MVC的小型Web应用程序。 Now I try implement main classes for Model layout using DAO pattern. 现在,我尝试使用DAO模式为模型布局实现主类。

So, first of all I create two entity classes (for example): Author and Book: 因此,首先,我创建两个实体类(例如):Author和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() . 下一步,我看到Book类和Author类都具有getId()setId() so, I create interface Persistent for my Entity classes: 因此,我为Entity类创建了Persistent接口:

 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? model包的正确实现?

On the next step, I start implement classes for package dao . 下一步,我开始实现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 下一步:创建接口AuthorDaoBookDao ,以扩展基础dao interface Dao

But both interfaces: AuthorDao and BookDao - at this moment empty. 但是两个接口:AuthorDao和BookDao-目前为空。 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. 最后一步,我创建包model.dao.hibernate并将其添加到类AuthorDaoHibernate和BookDaoHibernate中,这两个类都实现了AuthorDao和BookDao接口。

And My main question now: 我现在的主要问题是:

my interface Dao work with objects type Persistent and I dont use Generics. 我的界面Dao使用Persistent类型的对象,并且我不使用泛型。 And all ok and nice. 一切都很好。

What do you thinks - what benefits I have, if I re-work Dao interface wit Generics: 您的看法-如果我对Dao接口和泛型进行重新设计,我有什么好处:

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... 我的Dao类仅适用于持久性实体-没有其他任何对象类型...

Do you really any reasons in me case use Generics? 在我看来,您真的有任何理由使用泛型吗?

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): 这是一个基本示例(为简便起见,我将getter和setter方法省略):

@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 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);

If you want to use generics you should define Dao as following: 如果要使用泛型,则应按以下方式定义Dao:

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: 现在,当您扩展它时,您将必须创建仅接受Book的保存:

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

The benefit here is that you cannot pass Author to BookDao . 这样做的好处是您不能将Author传递给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. 顺便说一句,如果您使用的是Hibernate,JPA或其他ORM解决方案,则实际上不必为每个实体创建DAO。 One generic dao can solve all your needs. 一个通用的dao可以解决您的所有需求。

There is no reason here. 这里没有理由。 If it's unique, it's not generic, by definition ! 如果它是唯一的,那么根据定义它不是通用的! List getAll() will do the Job. 列表getAll()将完成任务。

The ArrayList is Generic because it will sometimes return Persistent, sometime President. ArrayList是泛型的,因为有时有时会返回Persistent。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM