2012-05-20 143 views
2

我正在编写一个网站的功能区/成就系统,我必须为我的系统中的每个功能区编写一些逻辑。例如,如果您在前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个色带,并且我不需要为其中任何一个添加其他列)。现在

,具体的丝带将实施这样的:

@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个用户中) 。

任何帮助非常感谢。

谢谢!

+0

您是否听说过SOLID?我认为你在这里打破了2个原则。 LSP(在您的类RibbonJpa实现功能区中)和ISP(功能区中的方法签名) – karlihnos

回答

10

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

很多人会说相反的是:它是一种反模式(anaemic domain model)在其他任何地方都有业务逻辑。有关更多信息,请参阅Domain-Driven Design

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

+0

感谢您提供此信息@Raedwald。很高兴知道我遵循正确的方式:)你知道为什么我无法在域对象中使用Autowire DAO(或任何其他组件)吗?任何解决方案谢谢。 – satoshi

+0

我是新来的春天,所以我无法帮助。听起来你应该问一个单独的问题。 – Raedwald

+0

注1:如果您计划在实体中实现业务逻辑,请注意,如果您将相同的作为分离对象传递,则客户端也可以访问业务逻辑。必须向客户提供数据而不是业务逻辑。注2:'FirstUsersRibbon'不需要'RibbonJpa'显式实现'Ribbon'接口。 – San

0

而且,我不能自动装配任何的DAO在实体

如果你使用Spring和Hibernate,看看http://jblewitt.com/blog/?p=129:这给出了一个类似的问题的一个很好的说明与各种解决方案。

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

+0

这不是SO风格就是把补充问题作为答案。你应该问这是一个单独的问题。 – Raedwald