Java 域对象中的业务逻辑

Java 域对象中的业务逻辑,java,spring,jpa-2.0,business-logic,autowired,Java,Spring,Jpa 2.0,Business Logic,Autowired,我正在为一个网站编写一个功能区/成就系统,我必须为系统中的每个功能区编写一些逻辑。例如,如果你在网站注册的前2000人中,或者在论坛上发布了1000篇帖子后,你就可以获得一条丝带。这个想法与stackoverflow的徽章非常相似,真的 因此,每个功能区显然都在数据库中,但它们也需要一些逻辑来确定用户何时获得了功能区 按照我的编码方式,Ribbon是一个简单的界面: public interface Ribbon { public void setId(int id); publ

我正在为一个网站编写一个功能区/成就系统,我必须为系统中的每个功能区编写一些逻辑。例如,如果你在网站注册的前2000人中,或者在论坛上发布了1000篇帖子后,你就可以获得一条丝带。这个想法与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个Ribbon那样编写代码,并且不需要为其中任何一个编写额外的列)

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

@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生成)

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

非常感谢您的帮助

谢谢大家!

问题是,在域对象中编写业务逻辑感觉是错误的

许多人会说,情况正好相反:在其他地方拥有业务逻辑是一种反模式(an)。有关更多信息,请参阅

然后,您可能会想知道传统3层体系结构的中间层是用来做什么的。它为应用程序提供了服务层。见我的相关问题“”

此外,我无法自动关联实体中的任何DAO

如果您使用的是Spring和Hibernate,请看一下:这很好地描述了具有各种解决方案的类似问题


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

感谢您提供此信息,@Raedwald。很高兴知道我遵循了正确的方法:)你知道为什么我不能在域对象中自动连接DAO(或任何其他组件)吗?有什么解决办法吗?谢谢。我是春天的新手,所以我没办法。听起来您应该问一个单独的问题。注意1:如果您计划在实体中实现业务逻辑,请注意,如果您将其作为分离对象传递,那么客户端也可以访问业务逻辑。必须向客户机提供数据,而不是业务逻辑。注2:
FirstUsersRibbon
不需要像
RibbonJpa
那样显式实现
Ribbon
接口。将补充问题作为答案不是一种风格。你应该单独问这个问题。你听说过SOLID吗?我认为你在这里违反了两条原则。LSP(在类RibbonJpa实现Ribbon中)和ISP(Ribbon中的方法签名)