域对象中的业务逻辑

时间:2012-05-20 19:34:42

标签: java spring jpa-2.0 business-logic autowired

我正在为网站编写功能区/成就系统,我必须为系统中的每个功能区编写一些逻辑。例如,如果您是第一批注册到该网站的2,000人或者在论坛中发布了1,000个帖子后,您就可以获得一个功能区。这个想法非常类似于stackoverflow的徽章,真的。

因此,每个功能区显然都在数据库中,但它们还需要一些逻辑来确定用户何时获得功能区。

在我编码的方式中,Ribbon是一个简单的界面:

public interface Ribbon {
    public void setId(int id);
    public int getId();
    public String getTitle();
    public void setTitle(String title);
    public boolean isEarned(User user);
}

RibbonJpa是一个实现Ribbon接口的抽象类,避免了isEarned()方法的定义:

@Entity
@Table(name = "ribbon")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "ribbon_type")
public abstract class RibbonJpa implements Ribbon {
    @Id
    @Column(name = "id", nullable = false)
    int id;

    @Column(name = "title", nullable = false)
    private String title;

    @Override
    public int getId() {
        return id;
    }

    @Override
    public void setId(int id) {
        this.id= id;
    }

    @Override
    public String getTitle() {
        return title;
    }

    @Override
    public void setTitle(String title) {
        this.title = title;
    }
}

您可以看到我将继承策略定义为SINGLE_TABLE(因为我必须像50条带一样编码,而且我不需要为其中任何一条添加其他列)。

现在,将实现一个特定的功能区:

@Entity
public class FirstUsersRibbon extends RibbonJpa implements Ribbon {
    public FirstUsersRibbon() {
        super.setId(1);
        super.setTitle("First 2,000 users registered to the website");
    }

    @Override
    public boolean isEarned(User user) {
        // My logic to check whether the specified user has won the award
    }
}

这段代码工作正常,表格是按照我期望的方式在数据库中创建的(我在本地环境中使用DDL生成)。

问题是,在域对象中编写业务逻辑是错误的。这是好习惯吗?你能提出更好的解决方案吗?此外,我无法在实体(FirstUsersRibbon)中自动装配任何DAO,我在业务逻辑中需要它们(在这种情况下,我需要DAO来检查用户是否在注册的前2,000个用户中到网站)。

非常感谢任何帮助。

谢谢!

2 个答案:

答案 0 :(得分:10)

  

问题是,在域对象中编写业务逻辑感觉不对。

许多人会说反过来是正确的:在其他地方拥有业务逻辑是一种反模式(anaemic domain model)。有关详细信息,请参阅Domain-Driven Design

您可能会想知道传统3层架构的中间层是什么。它为应用程序提供服务层。请参阅我的相关问题“What use are EJBs?”。

答案 1 :(得分:0)

  

另外,我无法在实体中自动装配任何DAO

如果您正在使用Spring和Hibernate,请查看http://jblewitt.com/blog/?p=129:这可以很好地描述各种解决方案中的类似问题。

如果您正在以您描述的方式寻找丰富的域模型,那么通过Spring实例化域对象可能是个好主意,因此能够将DAO注入您的域对象。