java swing应用程序中的服务层

我在想如果我真的需要服务层。

我为桌面摆动应用程序使用spring + hibernate,此时我有gui / swing图层 - >服务图层 - > dao图层。 我仅在@Transactional支持和IOC注入中使用弹簧

最好的做法是说我必须编写一个服务来使用我的daos,并将所有的事务管理放入服务中。

但我非常经常意识到,服务层只能复制dao方法,例如:

// a DAO example
@Repository
public class CustomerHibernateDAO extends BaseHibernateDAO implements CustomerDAO {

 public List<Customer> findAllCustomerILikeName(String name){
  return getSession()
   .createCriteria(Customer.class)
   .add(Restriction.ilike("name", name))
   .list();
 }
}

// Customer service to use this dao...
@Service
@Transactional
public class CustomerService {

 @Autowired
 CustomerDAO customerDAO;

 // Why i can't call DAO instead the service?
 public List<Customer> getAllCustomersByName(String name){
      return customerDAO.findAllCustomerILikeName(name);
 }

}

这是矿山服务层的典型用法...... Hibernate是db-agnostic,spring是tecnology-agnostic:所以,我真的需要它吗?

怎么样一个独特的服务类来管理所有的DAO? 我认为这可能是一个很好的妥协,或者是一个不好的做法?

我知道把@Transactional放在DAO上是一种不好的方法,但是现在我必须编写仅用于放置@Transactional的服务......

编辑

有关我的应用的更多信息。

我的应用程序是一个管理软件和管理用户注册,产品,订单和其他类似的东西。 在实践中,它包含大量的读实体 - >编辑 - >保存实体或创建 - >编辑 - >保存操作,并且,由于休眠,大部分时间这些操作都由一个dao管理,因此使用@manyto休眠。 .. collection和cascade.save_update允许在同一个持久操作中保存两个或多个实体。

因此,例如,在我可以插入,编辑或创建项目(要销售的产品)的项目JFrame中,有:

public ItemFrame(){
 // the constructor
 itemService=springAppContext.getBeans(ItemService.class);
}

public boolean validateForm(){
 // test if the gui is correctly filled by user
}

public boolean save(){
 // create an Item entity taking value from swing gui(JTextField etc)
 Item item=new Item();
 item.setName(nameTextField.getText());
 item.setEtc...
 // ItemService ' save method is a wrap around itemDao.save(item)...
 itemService.save(item);
}

private void saveItemActionPerformed(ActionEvent evt){
 // When i press SAVE button
 if(validateForm()){
  save();
 }
}

这是我在大多数情况下所拥有的,所以我认为我陷入了贫血领域反模式......

谢谢。


如果你的服务层重复道,你根本没有使用服务层。 我在很少的应用程序中犯了同样的错误,我想知道“服务层为什么看起来如此丑陋,以及是否重复DAO”......

服务层应该是你应用程序的接口,这意味着,某些方法在dao和服务中是不一样的,但主要部分是显着不同的。 我不能在没有查看其余代码的情况下说这些,但是通过你的问题(这与我几个月前的问题几乎相同),在我看来,你正在使用贫血域模型反模式。 在贫血的领域模型中,你的模型只包含字段和getter,没有真正的方法(行为),它违反了基本的面向对象的原则(对象==数据+行为)......你的行为可能是看起来像事务脚本服务层,但应该在您的模型(域图层)中。

解决方法是使用丰富的域模型(bean通过@Configurable注入到模型中)。 你可能会说,这违反了图层模式,你可能是正确的。 但我确信,我们应该将我们的应用程序(域+ dao +服务)视为一个单一组件(请参阅Alistair Cockburn六角形体系结构/端口和适配器)。

您的摇摆应用程序/ Web客户端将成为您的核心组件的客户端,然后您可以无任何限制地切换它们(因为所有数据都在核心)。

但是这种方法存在限制/缺点。 如果你将通过Hibernate使用某种安全性(Spring安全性)或活动记录,那么你应该通过DTO(而不是实体本身)与所有客户端交流,因为当你联系实体时,它可能会调用服务,服务将通过交易和可以修改数据库(绕过你的安全)。

我希望,我已经猜到了你的架构,如果没有,我很抱歉在这里发明车轮,但是这篇文章可能会帮助那些不知道这一点的人(就像我在几个飞蛾年前那样)。

编辑

到您的编辑:即使在简单的CRUD应用程序中,某种操作应该在服务层 - 例如验证(而不是验证“这是一个数字”,但是一些业务特定的验证)。 这不应该在你看来,因为如果你改变它,你将会复制并粘贴它。 当你看你的代码时,你应该问一个问题:“如果我决定编写瘦客户端(在Web浏览器中查看)”,是否有任何代码,我将不得不复制? 如果答案为是,则应该为此可能的远程呼叫创建一个服务方法。

你应该/可以在服务层上做的另一件事是自动化(是这个角色中的用户可以删除这个条目)。 比你几乎所有的实体都要有服务层,因为简单的用户应该能够编辑(删除)他的条目,但可能不应该删除其他用户。 但角色管理员中的用户可以执行此操作。

示例代码(我的应用程序中的文章服务接口的一部分(Spring安全性)):

@Secured("ROLE_EDITOR")
public void save(ArticleDTO selectedArticle, ArticleDetailsDTO selectedArticleDetails);

在评论服务中,大家可以将他们的评论保存到文章中....

最后一个提示:如果你需要服务层,你应该考虑一下。 当它以一种很好的方式书写时,您的应用程序将在其灵活性,可重用性和可维护性方面获得许多质量。 但编写它非常困难且耗时。 如果你不想这样做所有这些(安全,丰富的域模型,从更多的接口调用(改变视图实现)),你可以没有它的生活:-)


在某个时候,你的应用程序会需要一些业务逻辑。 此外,您可能需要验证输入以确保没有任何恶意或不正确的请求。 这个逻辑属于你的服务层。

此外,可能会使DAO变得非常通用,因此您只有一两种方法不会有太大改变。 这可以降低每次想要添加/更改应用程序功能时,对DAO类进行严重错误的风险。

DAO用于访问数据。 该服务用于业务逻辑。 让他们分开,从长远看你会更开心。


最终,您需要协调多个DAO之间的行为。 您可能还会在业务规则中引入一些复杂性(例如:如果[该]处于特定状态,则不要更新[this])。 这是服务层派上用场的地方。

也就是说,从技术上来说,完全消除服务层没有任何问题。 当你最终决定你需要一个时,它会更加痛苦。

链接地址: http://www.djcxy.com/p/48993.html

上一篇: Service layer in java swing application

下一篇: How do I convert a C# byte array into structured data?