我只是读这篇文章:业务逻辑(以及那是什么?)应该在哪里生存,以及如何用Spring来实现?
http://www.tutorialized.com/view/tutorial/Spring-MVC-Application-Architecture/11986
我觉得这很棒。它很好地解释了层架构,我很高兴我正在使用的架构非常符合他的描述。
但有一两件事,我似乎并没有得到:
第一:究竟什么是业务逻辑又是什么呢不是?在他所说的文章中(并且他不是唯一一个),业务逻辑应该放在领域模型中。因此Account
类应具有知道如何激活Account
的activate()
方法。根据我的理解,这可能涉及一些持久性工作。但是领域模型不应该有DAO的依赖。只有服务层应该知道DAO。
那么,业务逻辑就是一个域实体可以对自己做什么?与activate()
类似,方法会将active
属性设置为true
,并将dateActivated
属性设置为new Date()
,然后服务的任务是首先拨打account.activate()
和第二个dao.saveAccount(account)
?什么需要外部依赖去服务?这就是我到现在为止所做的。
public AccountServiceImpl implements AccountService
{
private AccountDAO dao;
private MailSender mailSender;
public void activateAccount(Account account)
{
account.setActive(true);
account.setDateActivated(new Date());
dao.saveAccount(account);
sendActivationEmail(account);
}
private void sendActivationEmail(Account account)
{
...
}
}
这与他所说的相反,我认为,不是吗?
我也没有得到的是关于如何使用像Account
这样的Spring线域对象的例子。如果Account自己发送电子邮件,则需要这样做。
鉴于此代码:
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
public class Account {
private String email;
private MailSender mailSender;
private boolean active = false;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public void setMailSender(MailSender mailSender) {
this.mailSender = mailSender;
}
public void activate() {
if (active) {
throw new IllegalStateException("Already active");
}
active = true;
sendActivationEmail();
}
private void sendActivationEmail() {
SimpleMailMessage msg = new SimpleMailMessage();
msg.setTo(email);
msg.setSubject("Congrats!");
msg.setText("You're the best.");
mailSender.send(msg);
}
}
如果我使用Hibernate,我可以以电汇mailSender
使用DependencyInjectionInterceptorFactoryBean
。如果我使用JDBC来代替,那么我真的会写下以下繁琐的代码?另外,当我在MVC控制器中为Account创建新实例时,让我们假设将它填充到模型中?
BeanFactory beanFactory = new XmlBeanFactory(
new ClassPathResource("chapter3.xml"));
Account account = new Account();
account.setEmail("[email protected]");
((AutowireCapableBeanFactory)beanFactory).applyBeanPropertyValues(
account, "accountPrototype");
account.activate();
这不可靠,很麻烦,不是吗?每当我看到一个Account的实例时,我都不得不问自己该创建对象的位置。此外,如果我采用这种方法:我没有可以传递的一个appContext.xml,但有几个,一个用于持久性,一个用于服务配置。我会怎么做?另外,每创建一个这样的实例或者我错过了什么,这会创建一个全新的上下文?
有没有更好的解决方案呢?
任何帮助,非常感谢。
扼杀,谢谢你的回答。所以,基本上我的建议是真实的,即业务逻辑是“业务实体可以独立完成而不使用其他层的东西”。其余的是服务任务(或基础设施或任何你称之为的)。对我来说有点意义,不过直觉上,我会打电话来决定是发送一封确认电子邮件还是不是“商业决策”,我想这就是让我困惑的原因。 – marc82ch 2012-07-30 11:20:16
是否发送确认电子邮件的决定 - 是的是“业务决策”,但发送不是业务任务。 :)我不确定这个决定是否是Account的职责范围。这很可能是AccountService的一项任务。 – masted 2012-07-30 12:54:08