简体   繁体   English

寻找设计模式以将框架层彼此隔离

[英]Looking for design patterns to isolate framework layers from each other

I'm wondering if anyone has any experience in "isolating" framework objects from each other (Spring, Hibernate, Struts). 我想知道是否有人有任何相互“隔离”框架对象的经验(Spring,Hibernate,Struts)。 I'm beginning to see design "problems" where an object from one framework gets used in another object from a different framework. 我开始看到设计“问题”,其中来自一个框架的对象被用于来自不同框架的另一个对象。 My fear is we're creating tightly coupled objects. 我担心的是我们正在创建紧密耦合的对象。

For instance, I have an application where we have a DynaActionForm with several attributes...one of which is a POJO generated by the Hibernate Tools. 例如,我有一个应用程序,其中我们有一个带有几个属性的DynaActionForm ...其中一个是由Hibernate Tools生成的POJO。 This POJO gets used everywhere...the JSP populates data to it, the Struts Action sends it down to a Service Layer, the DAO will persist it...ack! 这个POJO到处使用...... JSP将数据填充到它,Struts Action将它发送到服务层,DAO将保持它... ack!

Now, imagine that someone decides to do a little refactoring on that POJO...so that means the JSP, Action, Service, DAO all needs to be updated...which is kind of painful...There has got to be a better way?! 现在,想象某人决定对该POJO进行一些重构......这意味着JSP,Action,Service,DAO都需要更新......这有点痛苦......必须有一个更好的方法?!

There's a book called Core J2EE Patterns: Best Practices and Design Strategies (2nd Edition)...is this worth a look? 有一本名为Core J2EE Patterns:Best Practices and Design Strategies(第2版)的书......这值得一看吗? I don't believe it touches on any specific frameworks, but it looks like it might give some insight on how to properly layer the application... 我不相信它触及任何特定的框架,但看起来它可能会提供一些关于如何正确分层应用程序的见解......

Thanks! 谢谢!

For instance, I have an application where we have a DynaActionForm with several attributes...one of which is a POJO generated by the Hibernate Tools. 例如,我有一个应用程序,其中我们有一个带有几个属性的DynaActionForm ...其中一个是由Hibernate Tools生成的POJO。 This POJO gets used everywhere...the JSP populates data to it, the Struts Action sends it down to a Service Layer, the DAO will persist it...ack! 这个POJO到处使用...... JSP将数据填充到它,Struts Action将它发送到服务层,DAO将保持它... ack!

To me, there is nothing wrong with having Domain Objects as a "transveral" layer in a web application (after all, you want their state to go from the database to the UI and I don't see the need to map them into intermediate structures): 对我来说,将Domain Objects作为Web应用程序中的“transveral”层没有任何问题(毕竟,你希望他们的状态从数据库转到UI,我不认为需要将它们映射到中间层结构):

替代文字

Now, imagine that someone decides to do a little refactoring on that POJO...so that means the JSP, Action, Service, DAO all needs to be updated...which is kind of painful...There has got to be a better way?! 现在,想象某人决定对该POJO进行一些重构......这意味着JSP,Action,Service,DAO都需要更新......这有点痛苦......必须有一个更好的方法?!

Sure, you could read "Beans" from the database at the DAO layer level, map them into "Domain Objects" at the service layer and map the Domain Objects into "Value Objects" for the presentation layer and you would have very low coupling. 当然,您可以在DAO层级别从数据库中读取“Beans”,将它们映射到服务层的“域对象”,并将域对象映射到表示层的“值对象”,并且您将具有非常低的耦合。 But then you'll realize that: 但是你会意识到:

  1. Adding a column in a database usually means adding some information on the view and vice-versa. 在数据库中添加列通常意味着在视图上添加一些信息,反之亦然。
  2. Duplication of objects and mappings are extremely painful to do and to maintain. 对象和映射的重复是非常痛苦的事情和维护。

And you'll forget this idea. 你会忘记这个想法。

There's a book called Core J2EE Patterns: Best Practices and Design Strategies (2nd Edition)...is this worth a look? 有一本名为Core J2EE Patterns:Best Practices and Design Strategies(第2版)的书......这值得一看吗? I don't believe it touches on any specific frameworks, but it looks like it might give some insight on how to properly layer the application... 我不相信它触及任何特定的框架,但看起来它可能会提供一些关于如何正确分层应用程序的见解......

This book was a "showcase" of how to implement (over engineered) applications using the whole J2EE stack (with EJB 2.x) and has somehow always been considered as too complicated (too much patterns). 本书是如何使用整个J2EE堆栈(使用EJB 2.x)实现(过度设计)应用程序的“展示”,并且总是被认为太复杂(太多模式)。 On top of that, it is today clearly outdated. 最重要的是,它今天显然已经过时了。 So it is interesting but must be taken with a giant grain of salt. 所以它很有意思,但必须采用巨大的盐。

In other words, I wouldn't recommend that book (at least certainly not as state of the art). 换句话说,我不会推荐这本书(至少肯定不是最先进的)。 Instead, have a look at Real World Java EE Patterns - Rethinking Best Practices (see Chapter 3 - Mapping of the Core J2EE patterns into Java EE) and/or the Spring literature if you are not using Java EE. 相反,如果您不使用Java EE,请查看真实世界Java EE模式 - 重新思考最佳实践 (请参阅第3章 - 将核心J2EE模式映射到Java EE)和/或Spring文献。

First, avoid Struts 1. Having to extend a framework class (like DynaActionForm ) is one of the reasons this framework is no longer a good choice. 首先,避免Struts 1.必须扩展框架类(如DynaActionForm )是这个框架不再是一个好选择的原因之一。

You don't use spring classes in the usual scenarios. 在常规方案中,您不使用spring类。 Spring is non-invasive - it just wires your objects. 弹簧是非侵入性的 - 它只是连接你的物体。 You depend on it only if using some interfaces like ApplicationContextAware , or if you are using the hibernate or jdbc extensions. 只有在使用ApplicationContextAware接口或者使用hibernate或jdbc扩展时才依赖它。 Using these extensions together with hibernate/jdbc completely fine and it is not an undesired coupling. 将这些扩展与hibernate / jdbc一起使用就完全没问题了,这不是一个不受欢迎的耦合。

Update: If you are forced to work with Struts 1 (honestly, try negotiating for Struts 2, Struts 1 is obsolete!), the usual way to go was to create a copy of the Form class, that contained the exact same fields, but did not extend the framework class. 更新:如果您被迫使用Struts 1(老实说,尝试协商Struts 2,Struts 1已经过时了!),通常的方法是创建Form类的副本,其中包含完全相同的字段,但是没有扩展框架类。 There would be a factory method that takes the form class and returns the simple POJO. 将有一个工厂方法接受表单类并返回简单的POJO。 This is duplication of code, but I've seen it in practice and is not that bad (compared to the use of Struts 1 :) ) 这是代码的重复,但我在实践中看到它并没有那么糟糕(与使用Struts 1 :)相比)

I think your problem is not so big as it seems. 我认为你的问题不像看起来那么大。

Let's imagine, what can you really change in your POJO: 让我们想象一下,你在POJO中真正改变了什么:

1) name of its class: any IDE with refactoring support will automatically make all necessary changes for you 1)其类的名称:任何具有重构支持的IDE将自动为您进行所有必要的更改

2) add some field/method: it almost always means adding new functionality what is always should be done manually and carefully. 2)添加一些字段/方法:它几乎总是意味着添加新功能,总是应该手动和仔细地完成。 It usually cause to some changes in your service layer, very seldom in DAO, and usually in your view (jsp). 它通常会导致服务层发生一些变化,很少在DAO中,通常在您的视图中(jsp)。

3) change methods implementation: with good design this should cause any changes in other classes. 3)改变方法实现:具有良好的设计,这应该导致其他类的任何变化。

That's all, imho. 这就是全部,imho。

Make a decision about technology for implementing busyness-logic (EJB or Spring) and use its facilities of dependency injection. 决定实现繁忙逻辑(EJB或Spring)的技术并使用其依赖注入工具。 Using DI will make different parts of your program communicate to each other through interfaces. 使用DI将使程序的不同部分通过接口相互通信。 It should be enough for reaching necessary (small enough) level of coupling. 它应该足以达到必要的(足够小的)耦合水平。

It's always nice to keep things clear if you can and separate the layers etc. But don't go overboard. 如果可以并且将层分开等,那么保持清晰总是很好。但是不要过分。 I've seen systems where the developers were so intent on strictly adhering to their adopted patterns and practices that they ended up with a system worse than the imaginary one they were trying to avoid. 我已经看到系统开发人员如此倾向于严格遵守他们采用的模式和实践,他们最终得到的系统比他们试图避免的虚构系统更糟糕。

The art of good design is understanding the good practices and patterns, knowing when and how to apply them, but also knowing when it's appropriate to break or ignore them. 良好设计的艺术是理解良好实践和模式,知道何时以及如何应用它们,但也知道什么时候适合打破或忽略它们。

So take a good look at how you can achieve what you are after, read up on the patterns. 因此,请仔细研究如何实现您的目标,阅读模式。 Then do a trial on a separate proof of concept or a small part of your system to see your ideas in practice. 然后对单独的概念验证或系统的一小部分进行试验,以便在实践中查看您的想法。 My experience is that only once you actually put some code in place, do you really see the pros and cons of the idea. 我的经验是,只有当你真正实施一些代码时,你才真正看到了这个想法的优点和缺点。 Once you have done that, you will be able to make an informed decision about what you will or will not introduce. 完成后,您将能够就您将要或不会介绍的内容做出明智的决定。

Finally, it's possible to build a system which does handle all the issues you are concerned about, but be pragmatic - is each goal you are attempting to reach worth the extra code and APIs you will have to introduce to reach it. 最后,可以建立一个能够处理您所关注的所有问题但又务实的系统 - 您尝试达到的每个目标都值得为您提供额外的代码和API。

I'd say that Core J2EE Patterns: Best Practices and Design Strategies (2nd Edition) addresses EJB 2.0 concerns, some of which would be considered anti-patterns today. 我要说核心​​J2EE模式:最佳实践和设计策略(第2版)解决了EJB 2.0问题,其中一些问题今天被认为是反模式。 Knowledge is never wasted, but I wouldn't make this my first choice. 知识永远不会浪费,但我不会把它作为我的第一选择。

The problem is that it's impossible to decouple all the layers. 问题是,不可能将所有层分离。 Refactoring the POJO means modifying the problem you're solving, so all the layers DO have to be modified. 重构POJO意味着修改您正在解决的问题,因此必须修改所有层DO。 There's no way around that. 没有办法解决这个问题。

Pure decoupling of layers that have no knowledge of each other requires a lot of duplication, translation, and mapping to occur. 对彼此不了解的层进行纯粹的解耦需要进行大量的复制,转换和映射。 Don't fall for the idea that loose coupling means this work goes away. 不要认为松散耦合意味着这项工作消失了。

One thing you can do is have a service layer that's expressed in terms of XML requests and responses. 您可以做的一件事是拥有一个以XML请求和响应表达的服务层。 It forces you to map the XML to objects on the service side, but it does decouple the UI from the rest. 它强制您将XML映射到服务端的对象,但它确实将UI与其余部分分离。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM