【问题标题】:Java Generics. What benefit in my case?Java 泛型。对我来说有什么好处?
【发布时间】:2012-01-24 09:15:31
【问题描述】:

此时我开始研究基于 MVC 的小型 Web 应用程序。 现在我尝试使用 DAO 模式实现模型布局的主类。

所以,首先我创建了两个实体类(例如):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

    }

和书籍类:

  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

        }

在下一步中,我看到 Book 和 Author 类都有 getId()setId()。 所以,我为我的实体类创建接口Persistent

 package myProject.model.entity;

        public interface Persistent {

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


        }

所以,首先我的问题:

model 包的实现是否正确?

下一步,我开始为包 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);
}

下一步:创建接口AuthorDaoBookDao,扩展基础dao interface Dao

但是两个接口:AuthorDao 和 BookDao——此时都是空的。 你怎么看 - 它在正常情况下,接口是空的?这是我的第二个问题。

在最后一步,我创建包 model.dao.hibernate 并将包添加到类 AuthorDaoHibernate 和 BookDaoHibernate - 这两个类都实现了 AuthorDao 和 BookDao 接口。

我现在的主要问题是:

我的界面Dao 使用对象类型Persistent,我不使用泛型。一切都很好。

你怎么看 - 我有什么好处,如果我重新工作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);
}

我的 Dao 类仅适用于持久实体 - 没有任何其他对象类型...

你真的有任何理由在我的情况下使用泛型吗?

【问题讨论】:

    标签: java model-view-controller generics interface dao


    【解决方案1】:

    泛型可以极大地提高代码的可读性并减少可能由错误转换引起的错误。

    我们正在使用与您描述的类似的东西(请注意,需要接口实现)。

    这是一个基本示例(为简洁起见,我将不考虑 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
    }
    

    使用 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);
    

    【讨论】:

    • BaseEntity - 是否必须是抽象的?
    • @user471011 不,它不需要是抽象的,它只是没有被注释为一个实体,你不能持久化一个普通的 BaseEntity 实例。将BaseEntity 甚至BaseDAO 抽象化是有意义的,但为简洁起见,我将其省略了。
    • 我们可以详细讨论一下吗?通过邮件还是通过Skype?你会很难吗?
    • @user471011 很遗憾,我现在没有那么多时间,因为我在工作。
    • @user471011 如果您有更多问题,可以在这里问他们。其他人也可以提供帮助或可能会发现这些信息很有用。
    【解决方案2】:

    如果你想使用泛型,你应该如下定义 Dao:

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

    现在,当您扩展它时,您必须创建仅接受 Book 的保存:

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

    这里的好处是您不能将Author 传递给BookDao。这不会通过编译。

    顺便说一句,如果您使用 Hibernate、JPA 或其他 ORM 解决方案,您实际上不必为每个实体创建 DAO。一个通用的 dao 可以解决您的所有需求。

    【讨论】:

    • 实际上 void save(Book persistent); 如果实现与基本实现没有区别,甚至都不需要。
    • @Thomas,我 100% 同意你的看法。我什至写道,他根本不需要每个实体的 DAO。一个通用的实现就足够了。
    【解决方案3】:

    这里没有理由。如果它是唯一的,则根据定义,它不是通用的! List getAll() 将完成这项工作。

    ArrayList 是通用的,因为它有时会返回 Persistent,有时会返回 President。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-23
      • 2011-08-12
      相关资源
      最近更新 更多