状态图中初始伪状态是否可以有两条向外的转换?

  这两天为一个初始状态是否可以有两条向外的转换给难住了。朋友说看看规范,我看了2.0的规范上说:

An initial pseudostate is shown as a small solid filled circle (see Figure 15.16). In a region of a classifierBehavior state

machine, the transition from an initial pseudostate may be labeled with the trigger event that creates the object; otherwise,

it must be unlabeled. If it is unlabeled, it represents any transition from the enclosing state.

这没有明确说明是否可以有两条。

  在argouml的用户组和umlchina上发信,一个argouml的外国用户朋友回了信,可是全是长难句,只模模糊糊懂了些。

我把问题和信也贴在这里,有谁看了知道答案说一下:

  argouml用户组的回信:

users@argouml.tigris.org

CC: umlchina@yahoogroups.com, nirvanax@tom.com, users@learndiary.tigris.org, iuking@163.com

From: "Dashing Meng" <learndiary_dashing@yahoo.com>  Add to Address Book  Add Mobile Alert

Yahoo! DomainKeys has confirmed that this message was sent by yahoogroups.com. Learn more

Date: Thu, 29 Dec 2005 01:18:42 -0800 (PST)

Subject: [UMLChina] Re: [argouml-users] ArgoUML told me,the initial state should has only one outgoing transition in a statechart diagram

   

Thanks for your answer very much.I understood most part of your answer except those very long sentence:),my english isn't well.

 

This is something I will model:

User(userID,userName)

Goal(goalID,goalName)

MyGoal(userID,goalID,goalState)

the relationship between User and Goal is :M:N,and MyGoal is the association class.

MyGoal has three states:processing,quited,finished.

 

People will join an existed goal,and write diary under a goal,like the operation model of http://www.43things.com

 

From a user's view,there are two ways he can create a new object of class MyGoal:a user join a goal directly without posting diary under it, and a user post an diary under a goal, when he do these,a new MyGoal's record will be insert into database and with the state:processing.

 

From the system's view,in fact,user join a goal is the operation like:

User.joinGoal(int GoalID),then a new MyGoal is created;

user post a diary under a goal is the operations below:

User.postDiary(int GoalID),and,if this is the first posting diary under this goal,this operation will call the previous operation:User.joinGoal(int GoalID).

 

So,in fact,the object of class MyGoal's creating is caused by User.joinGoal(int GoalID) only.

 

But,I am modeling a business model now and only from the user's view to do so,what do you think to treat this kind of things?

 

Thanks.

 

/Dashing Meng

Leif Holmgren <sm4rpq@amsat.org> wrote:

Hi!

As I have been tought and what I can make out of the UML standard the

initial state symbol is there just to show which of the other states the

object end up in when it is created. So there is no real transition from

the "initial state" and another state other than the one taken from the

big void when the object is created. The UML standard also specifies

that you can have only one initial state in each (sub)state-machine!

Unfortunately the UML standard is pretty messed up when it comes to

state machines so you have to read the text carefully to understand

this, and don't stop at the 1.4 standard as the newer ones are more

clear but still messy.

Exactly what are you trying to state with your model? Can your object

start off in one of two different states or are you treating the initial

state symbol as a state of it's own?

I would not model (or program for that matter) a class that have it's

object start off in two different states at all. I would instead create

an initial state (created) from which I immediately transit to one of

those that I really want to be in after initialization. When an object

has something that needs to be initialized at object creation time it

tends to be the same initialization no matter what lifecycle you want

the object to go through later on.

If you are just thinking of the initial state as a proper state you

just have to add an extra state and then two outgoing transitions from

that one (properly named and guarded of cource) and you are back on track.

/Leif

Dashing Meng wrote:

> Hi,All,

> There are two path from the initial state can enter the state call

> "Processing".But when I draw two outgoing transition from the initial

> state,The ArgoUML said:

> This Initial state has an invalid number of transitions. Normally

> Initial states have at most one outgoing transition.

> Defining correct state transitions is needed to complete the

> behavioral specification part of your design.

> To fix this, remove transitions by clicking on transition in the

> diagram and pressing the "Ctrl-Delete" key.

>

> So I added a Junction between the initial state and state

> "Processing".Is this way all right?

>

> Thanks.

>

> ------------------------------------------------------------------------

  umlchina上的回答:

From: <alexzhang@...>

Date: Wed Dec 28, 2005  8:40 pm

Subject: RE: [UMLChina] Re: ArgoUML told me,the initial state should has only one outgoing transition in a statechart diagram  alexzhang@...

 Send Email 

Hi Dashing,

I think this quesiton is tool  independent. You should refer to the state chart specification to see how it is prescribed in UML.

I urgently recommend we should learn from UML specification as the root cause.

 

 

Regards,

 

Alex Zhang

___________

GDNT, G124

ESN: 554-8782

-----Original Message-----

From: UMLChina@yahoogroups.com [mailto:UMLChina@yahoogroups.com] On Behalf Of Dashing Meng

Sent: Wednesday, December 28, 2005 8:36 PM

To: UMLChina@yahoogroups.com

Subject: RE: [UMLChina] Re: ArgoUML told me,the initial state should has only one outgoing transition in a statechart diagram

But,is there anyone can answer my question? If a initial state can has outgoing transition more than one in a state diagram?

http://learndiary.tigris.org/source/browse/learndiary/old/documentatio

n/easy_diary/design/pictures/MyGoalInfoStateChart.gif?

rev=1.1&view=markup

I am a UML self-learner,please tell me all the errors of mine.

Thanks a lot.

Dashing Meng <learndiary_dashing@yahoo.com> wrote:

ArgoUML is 100 percent free open source UML tool,it has been developing for 10 years,the main reason I using it in our open source project-LearnDiary is the spirit of ArgoUML developing Team.

Because we use a UML tool only for open source non-commerial developing for learning purpose.So we don't need a very powerful commerial UML tool.

In fact,I found ArgoUML is a little hard to use at first,but after using it some days,I have known some little skills for avoiding its defects and do some model with ArgoUML happily.

Thanks for introducing Visual Paradigm for UML for all of us.

Alex Guo <Alex.Guo@BenQ.com> wrote:

Hi, everyone

脗 脗 脗  Have you try Visual Paradigm for UML, it芒鈧劉s a perfect tool for draw UML diagram.

 

 

 

 

 

-----------------

Alex Guo

2005

--------------------------------------------------------------------------------

From: UMLChina@yahoogroups.com [mailto:UMLChina@yahoogroups.com] On Behalf Of Dashing Meng

Sent: Wednesday, December 28, 2005 4:01 PM

To: UMLChina@yahoogroups.com

Subject: RE: [UMLChina] Re: ArgoUML told me,the initial state should has only one outgoing transition in a statechart diagram

 

All is in http://argouml.tigris.org

Here is its last version of all things:include source,binary distribution,user manual,etc..

:http://argouml-downloads.tigris.org/argouml-0.20.ALPHA_4/

alexzhang@gdnt.com.cn wrote:

Hi

Dou you have the User Guide to ArgoUML?

Regards,

 

Alex Zhang

___________

GDNT, G124

ESN: 554-8782

-----Original Message-----

From: UMLChina@yahoogroups.com [mailto:UMLChina@yahoogroups.com] On Behalf Of learndiary_dashing

Sent: Wednesday, December 28, 2005 11:15 AM

To: UMLChina@yahoogroups.com

Subject: [UMLChina] Re: ArgoUML told me,the initial state should has only one outgoing transition in a statechart diagram

 

  可能是我没有正确的表达自己的意思吧:)

ArgoUML有个模型正确性的自动判定功能,也就是他们说的:cognitive

support.

  当我在状态机图的初始状态后面画了两条进入下一状态的转换线时,它告诉

我一般初始状态只能有最多一条向外的转换线。

  于是,我在初始状态和下一状态间加了一个分支点:Junction,然后ArgoUML

就不报错了。状态机图见下:

http://learndiary.tigris.org/source/browse/learndiary/old/documentatio

n/easy_diary/design/pictures/MyGoalInfoStateChart.gif?

rev=1.1&view=markup

  我想问:从UML规范来说,一个初始状态是不是只能有一条向外的转换

线?如果不能,假设我的真实的第一个状态有两条路径都可以进入,我怎样来表

达这种需求呢?

  我没有在课堂上学过UML,用语不规范或其他的任何不当的地方还望给予

指出。

  谢谢。

http://www.learndiary.com

http://develop.learndiary.com

LearnDiay Develop Group

--- In UMLChina@yahoogroups.com, ZhangChaoYang <from_mfc@y...> wrote:

>

> 他的意思可能是认为initState只是一个虚拟状态,不是真实存在的,所以要

定义一个真正的初始状态,比如idel状态

>

> Dashing Meng <learndiary_dashing@y...> wrote: Hi,All,

> There are two path from the initial state can enter the state

call "Processing".But when I draw two outgoing transition from the

initial state,The ArgoUML said:

> This Initial state has an invalid number of transitions. Normally

Initial states have at most one outgoing transition.

> Defining correct state transitions is needed to complete the

behavioral specification part of your design.

> To fix this, remove transitions by clicking on transition in the

diagram and pressing the "Ctrl-Delete" key.

>

> So I added a Junction between the initial state and

state "Processing".Is this way all right?

>

> Thanks.

>

  

真是惭愧,至今也没有通读一遍Struts的教程

  电子教程倒是下了好几本,都是临到用时去翻。一些基本的东西的概念也是模糊的。像<html:link/>的用法。我就记不得了。书上说:

  The html:link tag renders an HTML anchor tag (i.e., a hyperlink). This tag uses a lot of the same common

attributes as described earlier.You have multiple options for rendering the URL of a hyperlink. You can use the

href, action, forward, or page attributes to specify the URL.

 The href attribute is used to specify a full

URL without any knowledge of the web context of this web application.

 The page attribute is used to specify a

web context relative link.

 The action attribute is used to specify a link to an action mapping, as described in the

Struts config file.

 The forward attribute is used to specify a link to a global forward, as described in the Struts

config file.

Tip: TIP: If you are following a Model 2/MVC architecture, then you should use the page attribute and

the href attribute sparingly. In fact, you should almost never use the page attribute. The href

attribute should only be used to link to resources that are not in the current web application. This helps

you separate the controller from the View by not letting the View select the next View directly. Only the

controller should select the next View. Using the action and forward attributes instead forces you

to delegate selection of the next View to the controller.

Here is an example of linking to an action (/html-link.do) with the page attribute:

<html:link page="/html-link.do">

Linking with the page attribute.

</html:link>

Notice that you do not have to specify the web context of the web application. Conversely, if you used the href

attribute, you would have to specify the web context as follows (where the context is struts-exercise):

<html:link href="/struts-exercise-taglib/html-link.do">

Using Href

</html:link>

Obviously, it is better to use the page attribute when you are linking to things in the same web application (thus,

the same context). You can also use the href attribute to create links that are not on the same server as follows:

<html:link

href="http://otherserver/strutsTut/html-link.do">

Using Href

</html:link>

Another way to link to the html-link.do action is to use the action attribute as follows:

<html:link action="/html-link">

Using Action attribute

</html:link>

(转帖)Wiring Your Web Application with Open Source Java(3)

(由admin转自:http://www.onjava.com/pub/a/onjava/2004/04/07/wiringwebapps.html?page=3)

[译者注:欢迎大家直接在这篇译文中修改和完善,并留下你的联系方式。]

Now that we have our container service beans configured and wired together we need to wire our business service object and our DAO object together. Then we need to wire these objects to the transaction manager.

现在我们已经配置了我们的容器服务beans和把它们连在了一起,我们需要把我们的业务服务对象和我们的DAO对象连在一起。然后,我们需要把这些对象和事务manager连起来。

 

Here is what this looks like in the Spring configuration file:

这是在Spring配置文件里的样子:

<!-- ORDER SERVICE -->

<bean id="orderService"

  class="org.

         springframework.

         transaction.

         interceptor.

         TransactionProxyFactoryBean">

  <property name="transactionManager">

    <ref local="myTransactionManager"/>

  </property>

  <property name="target">

    <ref local="orderTarget"/>

  </property>

  <property name="transactionAttributes">

    <props>

      <prop key="find*">

     PROPAGATION_REQUIRED,readOnly,-OrderException

      </prop>

      <prop key="save*">

     PROPAGATION_REQUIRED,-OrderException

      </prop>

    </props>

  </property>

</bean>

<!-- ORDER TARGET PRIMARY BUSINESS OBJECT:

Hibernate implementation -->

<bean id="orderTarget"

         class="com.

                meagle.

                service.

                spring.

                OrderServiceSpringImpl">

  <property name="orderDAO">

    <ref local="orderDAO"/>

  </property>

</bean>

<!-- ORDER DAO OBJECT -->

<bean id="orderDAO"

         class="com.

                meagle.

                service.

                dao.

                hibernate.

                OrderHibernateDAO">

  <property name="sessionFactory">

    <ref local="mySessionFactory"/>

  </property>

</bean>

Figure 4 is an overview of what we have wired together. This shows how each object is related and set into other objects by Spring. Compare this with the Spring configuration file in the sample application to see these relationships.

图4是我们已经连在一起的东西的一个概览。它展示了每个对象是怎样被关联的和怎样被Spring设置进其它对象中。把这幅图和Spring配置文件在示例应用中对比看它们之间的关系。

Figure 4. This is how Spring will assemble the beans based on this configuration.

图4:这是Spring怎样将在这个配置的基础上装配beans。

This example uses a TransactionProxyFactoryBean, which has a setter for a transaction manager that we have already defined. This is a convenience object that knows how to deal with declarative transaction handling and your service objects. You can define how transactions are handled through the transactionAttributes property, which defines patterns for method names, and how they participate in a transaction. For more information about configuring isolation levels and commits or rollbacks on a transaction see TransactionAttributeEditor.

这个例子使用一个TransactionProxyFactoryBean,它有一个为我们已经定义了的事务管理者准备的setter。这是一个方便的对象,它知道怎样处理声明的事务操作和你的服务对象。你可以通过transactionAttributes属性定义事务怎样被处理,transactionAttributes属性为方法名定义模式和它们怎样参与进一个事务。获得更多的关于在一个事务上配置隔离层和提交或回滚看TransactionAttributeEditor。

The class TransactionProxyFactoryBean also has a setter for a target, which will be a reference to our business service object called orderTarget. The orderTarget bean defines which business service class to use and it has a property which refers to setOrderDAO(). This property will populate the orderDAO bean that is our DAO object to communicate with our persistence layer.

TransactionProxyFactoryBean类也有一个为一个target的setter,target将是一个到我们的叫作orderTarget的业务服务对象的引用。 orderTarget bean定义使用哪个业务服务对象和有一个指向setOrderDAO()的属性。这个属性orderDAO bean将居于其中,orderDAO bean是我们的和持久层交流的DAO对象。

One more note about Spring and beans is that beans can operate in two modes. These are defined as singleton and prototype. The default mode for a bean is singleton that means that one shared instance of the bean will be managed. This is used for stateless operations like a stateless session bean would provide. The prototype mode allows new instances of the bean to be create when the bean is served through Spring. You should only use prototype mode when each user needs their own copy of the bean.

还有一个关于Spring和bean要注意的是bean能以两种模式运作。这两种模式被定义为singleton和prototype.为一个bean默认的模式是singleton,意味着一个共享的bean的实例将被管理。这是用于像一个无状态会话bean将提供的无状态操作。prototype模式允许当bean被通过Spring服务时新的bean的实例被创建。你应当仅仅在每一个用户需要他们自己的bean的拷贝时使用prototype模式。

Providing a Service Locator

Now that we have wired up our services with our DAO we need to expose our services to other layers. This is generally used from code in a layer such as UI that uses Struts or Swing. An easy way to handle this is with a service locator patterned class to return resources from a Spring context. This can also be done directly through Spring by referencing the bean ID.

提供一个服务定位器

  现在我们已经把我们的服务和我们的DAO连起来了,我们需要暴露我们的服务给其它层。这通常被从在一个像在使用Struts或Swing的用户界面的层里的代码使用。一个处理这个容易的方法是使用一个服务定位器模式的类来从一个Spring上下文中返回资源。这也能通过Spring引用bean ID被直接完成。

Here is an example of how a service locator can be configured in a Struts Action:

这儿是一个服务定位器怎样能被配置在一个Struts Action中的示例:

public abstract class BaseAction extends Action {

  private IOrderService orderService;

  public void setServlet(ActionServlet

                                 actionServlet) {

    super.setServlet(actionServlet);

    ServletContext servletContext =

               actionServlet.getServletContext();

    WebApplicationContext wac =

      WebApplicationContextUtils.

         getRequiredWebApplicationContext(

                                 servletContext);

      this.orderService = (IOrderService)

                     wac.getBean("orderService");

  }

  protected IOrderService getOrderService() {

    return orderService;

  }

}

UI Layer Configuration

The UI Layer for the example application uses the Struts framework. Here we will discuss what is related to Struts when layering an application. Let's begin by examining an Action configuration within the struts-config.xml file.

用户界面层配置

  示例应用的用户界面层使用Struts框架。这儿我们将讨论当分层一个应用时和Struts相关的东西。让我们从检查在struts-config.xml文件里的一个Action配置开始。

  

<action path="/SaveNewOrder"

    type="com.meagle.action.SaveOrderAction"

    name="OrderForm"

    scope="request"

    validate="true"

    input="/NewOrder.jsp">

  <display-name>Save New Order</display-name>

  <exception key="error.order.save"

    path="/NewOrder.jsp"

    scope="request"

    type="com.meagle.exception.OrderException"/>

  <exception key="error.order.not.enough.money"

    path="/NewOrder.jsp"

    scope="request"

    type="com.

          meagle.

          exception.

          OrderMinimumAmountException"/>

  <forward name="success" path="/ViewOrder.jsp"/>

  <forward name="failure" path="/NewOrder.jsp"/>

</action>

The SaveNewOrder Action is used to persist an order that the user submitted from the UI layer. This is a typical Struts Action; however, notice the exception configuration for this action. These exceptions are also configured in the Spring configuration file, applicationContext-hibernate.xml, for our business service objects in the transactionAttributes property. When these exceptions get thrown back from the business layer we can handle them appropriately in our UI. The first exception, OrderException, will be used by this action when there is a failure saving the order object in the persistence layer. This will cause the transaction to rollback and propagate the exception back through the business object to the Struts layer. The OrderMinimumAmountException will also be handled in a transaction within the business object logic that fails when the order placed does not meet the minimum order amount. Again, the transaction will rollback and this exception can be handled properly by the UI layer.

SaveNewOrder Action被用来持久化一个用户从用户界面层提交的订单。这是一个典型的Struts Action;然而,注意这个action的异常配置。这些异常为在transactionAttributes属性里的我们的业务服务对象也被配置在Spring配置文件里,applicationContext-hibernate.xml。当这些异常被从业务层掷回我们能在我们的用户界面里恰当的处理它们。第一个异常,OrderException,当在持久层里有一个保存订单对象失败时将被这个action使用。这当引起事务回滚和通过业务对象传递异常回Struts层。OrderMinimumAmountException在业务对象逻辑里的一个事务因为提交的订单达不到最小订单数量而失败也将被处理。然后,事务将回滚和这个异常能被用户界面层恰当的处理。

[注:由admin翻译上述部分2005年12月31日22:59分;由***在***修改了上述部分;由***在***修改了上述部分...请自行填写,以便联系]

The last wiring step is to allow our presentation layer to interact with our business layer. This is done by using the service locator that was previously discussed. The service layer acts as an interface to our business logic and persistence layer. Here is how the SaveNewOrder Action in Struts might use a service locator to invoke a business method:

最后一个连接步骤是允许我们的表现层和我们的业务层交互。这可以通过使用前面讨论的服务定位器来完成。服务层扮演一个到我们的业务逻辑层和持久层的接口。这儿是 在Struts中的SaveNewOrder Action怎样可能使用一个服务定位器调用一个业务方法:

public ActionForward execute(

  ActionMapping mapping,

  ActionForm form,

  javax.servlet.http.HttpServletRequest request,

  javax.servlet.http.HttpServletResponse response)

  throws java.lang.Exception {

  OrderForm oForm = (OrderForm) form;

  // Use the form to build an Order object that

  // can be saved in the persistence layer.

  // See the full source code in the sample app.

  // Obtain the wired business service object

  // from the service locator configuration

  // in BaseAction.

  // Delegate the save to the service layer and

  // further upstream to save the Order object.

  getOrderService().saveNewOrder(order);

  oForm.setOrder(order);

  ActionMessages messages = new ActionMessages();

  messages.add(

      ActionMessages.GLOBAL_MESSAGE,

new ActionMessage(

      "message.order.saved.successfully"));

  saveMessages(request, messages);

  return mapping.findForward("success");

}

Conclusion

This article covers a lot of ground in terms of technology and architecture. The main concept to take away is how to better separate your application, user interface, persistence logic, and any other application layer you require. Doing this will decouple your code, allow new code components to be added, and make your application more maintainable in the future. The technologies covered here address specific problems well. However, by using this type of architecture you can replace application layers with other technologies. For example, you might not want to use Hibernate for persistence. Since you are coding to interfaces in your DAO objects it should be apparent to you how you might use another technology or framework, such as iBATIS, as a substitute. Or you might want to replace your UI layer with a different framework than Struts. Switching UI layer implementations should not directly affect your business logic or your persistence layer. Replacing your persistence layer should not affect your UI logic or business service layer. Wiring a web application is not a trivial task but it can be made easier to deal with by decoupling your application layers and wiring it together with suitable frameworks.

结论

这篇文章按照技术和架构覆盖了许多话题。从中取出的主要思想是怎样更好的分离你所需要的应用层、用户界面层、持久逻辑层、和其它任何应用层。这样做将解耦你的代码,允许新的代码组件被加入,使你的应用在将来更加可维护。这里覆盖的技术较好的解决特定的问题。然而,使用这种架构你能用其它的技术代替应用层。例如,你也许不想使用Hibernate持久化。因为你在你的DAO对象中编码到接口,你可能怎样使用其它的技术或框架,比如 iBATIS,作为一个替代是显而易见的。或者你可能用不同于Struts的框架替代你的UI层。改变UI层的实现不会直接影响你的业务逻辑层或者你的持久层。替换你的持久层应该不会影响你的UI逻辑或业务服务层。连接一个web应用不是一个小的任务,但是,靠解耦你的各应用层和用适当的框架组成它,它能变得更容易处理。

Mark Eagle is a Senior Software Engineer at MATRIX Resources, Inc. in Atlanta, GA. 

Mark Eagle 是一位在MATRIX智囊团的高级软件工程师, Inc. in Atlanta, GA。

[注:由admin翻译完全文第一遍于2006年1月1日9:59分;由***在***修改了上述部分;由***在***修改了上述部分...请自行填写,以便联系

全文:

(转帖)Wiring Your Web Application with Open Source Java(1) (1篇) http://www.learndiary.com/disDiaryContentAction.do?goalID=1408

(转帖)Wiring Your Web Application with Open Source Java(2) (1篇)http://www.learndiary.com/disDiaryContentAction.do?goalID=1409

(转帖)Wiring Your Web Application with Open Source Java(3) (1篇)http://www.learndiary.com/disDiaryContentAction.do?goalID=1410]

(转帖)Wiring Your Web Application with Open Source Java(2)

(由admin转自:http://www.onjava.com/pub/a/onjava/2004/04/07/wiringwebapps.html?page=2)

[译者注:欢迎大家直接在这篇译文中修改和完善,并留下你的联系方式。]

 

Wiring Together a Simple Example

Now that we understand the components from a high level, let's put this into practice. Again, for this example, we will combine the Struts, Spring, and Hibernate frameworks. Each one of these frameworks has too much detail to cover in one article. Instead of going into many details about each framework, this article will show how to wire them together with simple example code. The sample application will demonstrate how a request is serviced across each layer. A user of this sample application can save a new order to the database and view an existing order in the database. Further enhancements might allow the user to update or delete an existing order.

结合一个简单的例子

  现在,我们从一个高的层次理解了组件,让我们把这些用于实践。在这个例子中,我们将合并Struts、Spring、Hibernate框架。每一个这些框架在一篇文章中都有太多的细节覆盖到。这篇文章将用一个简单的例子代码展示怎样把它们结合在一起,而不是进入每个框架的许多细节。示例应用将示范一个请求怎样跨越每一层被服务。这个示例应用的一个用户能保存一个订单到数据库中和查看一个在数据库中存在的订单。进一步的提高也许允许用户更新或删除一个存在的订单。  

 

You can download the source code of the application.

你可以下载这个应用的源码。

First, we will create our domain objects since they will interoperate with each layer. These objects will allow us to define what should be persisted, what business logic should be provided, and what type of presentation interface should be designed. Next, we will configure the persistence layer and define object-to-relational mappings with Hibernate for our domain objects. Then we will define and configure our business objects. After we have these components we can discuss wiring these layers using Spring. Finally, we will provide a presentation layer that knows how to communicate with the business service layer and knows how to handle exceptions that arise from other layers.

  首先,我们将创建我们的领域对象因为它们将和每一层交互。这些对象将允许我们定义什么应该被持久化,什么业务逻辑应该被提供,和哪种表现界面应该被设计。然后,我们将配置持久层和为我们的领域对象用Hibernate定义“对象-关系”映射。然后,我们将定义和配置我们的业务对象。在有了这些组件后,我们能讨论和Spring把这些层连在一起。最后,我们将提供一个表现层,它知道怎样和业务服务层交流和知道怎样处理从其它层产生的异常。

Domain Object Layer

Since these objects will interoperate across all layers this might be a good place to start coding. This simple domain model will contain an object that represents an order and an object that represents a line item for an order. The order object will have a one-to-many relationship to a collection of line item objects. The example code has two simple objects in the domain layer:

com.meagle.bo.Order.java: contains the header-level information for an order.

com.meagle.bo.OrderLineItem.java: contains the detail-level information for an order.

Consider choosing package names for your objects that reflect how your application is layered. For example, the domain objects in the sample application can be located in the com.meagle.bo package. More specialized domain objects would be located in subpackages under the com.meagle.bo package. The business logic begins in the com.meagle.service package and DAO objects are located in the com.meagle.service.dao.hibernate package. The presentation classes for forms and actions reside in com.meagle.action and com.meagle.forms, respectively. Accurate package naming provides a clear separation for the functionality that your classes provide, allows for easier maintenance when troubleshooting, and provides consistency when adding new classes or packages to the application.

领域对象层

因为这些对象将和所有层交互,这也许是一个开始编码的好地方。这个简单的领域模型将包括一个代表一份订单的对象和一个代表一个订单项的对象。订单对象将和一组订单项对象有一对多的关系。例子代码在领域层有两个简单的对象:

com.meagle.bo.Order.java: 包括一份订单的概括信息;

com.meagle.bo.OrderLineItem.java: 包括一份订单的详细信息;

考虑为你的对象选择包名,它将反映你的应用是怎样分层的。例如:简单应用的领域对象可以放进com.meagle.bo包[译者注:bo-business object?]。更多专门的领域对象将放入在com.meagle.bo下面的子包里。业务逻辑在com.meagle.service包里开始,DAO对象被放进com.meagle.service.dao.hibernate包。对于forms和actions的表现类分别驻入com.meagle.action 和 com.meagle.forms包。准确的包命名为你的类提供的功能提供一个清楚的区分,考虑到当故障维护时更易于维护,当增加新的类或包给应用时提供一致性。

Persistence Layer Configuration

There are several steps involved in setting up the persistence layer with Hibernate. The first step is to configure our domain business objects to be persisted. Since Hibernate works with POJOs we will use our domain objects for persistence. Therefore the Order and OrderLineItem objects will need to provide getter and setter methods for all fields that they contain. The Order object would contain setter and getter methods such as ID, UserName, Total, and OrderLineItems in a standard JavaBean format. The OrderLineItem would similarly follow the JavaBean format for its fields.

Hibernate maps domain objects-to-relational databases in XML files. For our Order and OrderLineItem objects there will be two mapping files to express this. There are tools such as XDoclet to assist with this mapping. Hibernate will map the domain objects to these files:

Order.hbm.xml

OrderLineItem.hbm.xml

You will find these generated files in the WebContent/WEB-INF/classes/com/meagle/bo directory. The Hibernate SessionFactory is configured to know which database it is communicating with, the DataSource or connection pool to use, and what persistent objects are available for persistence. Session objects provided by the SessionFactory are the interface used to translate between Java objects and persistence functions such as selecting, saving, updating, and deleting objects. We will discuss configuring the SessionFactory that Hibernate requires to handle Session objects in a later section.

持久层配置

用Hibernate设置持久层涉及到几个步骤。第一步是配置我们的被持久化的领域对象。因为Hibernate和POJOs[译者注:Persistence Objects Java Objects?]一起工作,我们将使用我们的领域对象持久化。因此,订单和订单项对象将需要提供它们包括的所有的字段的getter和setter方法。订单对象将包括像ID、用户名、合计、和订单项这样一些字段的以一种标准的JavaBean的格式的setter和getter方法。订单项对象将同样的用JavaBean的格式为它的字段设置setter和getter方法。

  Hibernate在XML文件里映射领域对象到关系数据库。为我们的订单和订单项对象将有两个映射文件来表达这种映射。有像XDoclet这样的工具来帮助这种映射。Hibernate将映射领域对象到这些文件:

Order.hbm.xml

OrderLineItem.hbm.xml

你可以在WebContent/WEB-INF/classes/com/meagle/bo目录里找到这些生成的文件。Hibernate SessionFactory被配置来知道它正和哪种数据库交流、使用哪种数据源或连接池、什么持久的对象被持久化是有效的。被SessionFactory提供的Session对象是用于在Java对象和像选取、保存、更新、删除对象这样的一些持久化功能间的翻译的接口。我们将在后面的小节讨论配置Hibernate处理Session对象需要的SessionFactory。

Business Layer Configuration

Now that we have our domain objects we need to have business service objects that perform application logic, make calls to the persistence layer, take requests from the UI layer, deal with transactions, and handle exceptions. To wire all of this together and make this easy to manage we will use the bean management aspect of the Spring framework. Spring uses inversion of control (IoC), or setter dependency injection, to wire up objects that are referenced in an external XML file. Inversion of control is a simple concept that allows objects to accept other objects that are created at a higher level. This way your object is free from having to create objects and reduces object coupling.

Here is an example of an object creating its dependencies without IoC, which leads to tight object coupling:

Figure 2. Objects arranged without IoC. Object A creates objects B and C.

And here is an example with IoC that allows objects to be created at higher levels and passed into objects so that they can use the implementations directly:

Figure 3. Objects arranged with IoC. Object A contains setter methods that accept interfaces to objects B and C. This could have also been achieved with constructors in object A that accepts objects B and C.

业务层配置

  现在,我们有了我们的领域对象,我们需要有业务服务对象来执行应用逻辑、执行向持久层的调用、获得从用户界面层的请求、处理事务、处理异常。为了把所有这些连在一起使它易于管理,我们将使用Spring框架的bean管理方面的功能。Spring使用“控制反转”(IoC),或者“setter依赖注入”来把这些对象连好,这些对象在一个外部的XML文件中被引用。“控制反转”是一个简单的概念,它允许对象接受其它在一个高一些的层次创建的对象。使用这种方法,你的对象从必须创建其它对象中解放出来和减少对象耦合。

  这儿是个不使用IoC的对象创建它的从属对象的例子,这导致紧的对象耦合:

  图2:没有使用IoC的对象组织。对象A创建对象B和C。

  这儿是一个使用IoC的例子,它允许对象在一个高一些层次被创建和传进对象,所以它们能直接使用现存的对象:

  图3:对象使用IoC组织。对象A包含setter方法,它们接受到对象B和C的接口。这也可以用对象A里的接受对象B和C的构建器完成。

Building Our Business Service Objects

The setters we will use in our business objects accept interfaces that allow loosely defined implementations of the objects that will be set, or injected. In our case we will allow our business service object to accept a DAO to handle the persistence of our domain objects. While the examples in this article use Hibernate, we can easily switch implementations to a different persistence framework and inform Spring of the new implementation DAO object to use. You can see how programming to interfaces and using the dependency injection pattern loosely couples your business logic from your persistence mechanism.

Here is the interface for the business service object that is stubbed for a DAO object dependency:

建造我们的业务服务对象

  我们将在我们的业务对象中使用的setter方法接受接口,这些接口允许将被设置或者注入的对象的宽松实现。在我们这个例子里我们将允许我们的业务服务对象接受一个DAO去控制我们的领域对象的持久化。虽然在这篇文章的例子中使用Hibernate,我们可以容易的转换到一个不同的持久框架的实现,通知Spring使用新的实现的DAO对象。你将看见怎样编程到接口和使用“依赖注入”模式宽松耦合你的业务逻辑和你的持久化机制。

  这儿是业务服务对象的接口,它有一个DAO对象依赖的桩。[译者注:是setOrderDAO方法吗?]

public interface IOrderService {

  public abstract Order saveNewOrder(Order order)

    throws OrderException,

           OrderMinimumAmountException;

  public abstract List findOrderByUser(

                                     String user)

                           throws OrderException;

  public abstract Order findOrderById(int id)

                           throws OrderException;

  public abstract void setOrderDAO(

                             IOrderDAO orderDAO);

}

Notice that the code above has a setter for a DAO object. There is not a getOrderDAO method because it is not necessary since there is often no need to access the wired OrderDAO object from the outside. The DAO object will be used to communicate with our persistence layer. We will wire the business service object and the DAO object together with Spring. Because we are coding to interfaces, we do not tightly couple the implementation.

  注意上面的代码有一个为DAO对象准备的setter方法。这儿不是一个getOrderDAO方法因为它不是必要的,因为不太有从外面访问连着的OrderDAO对象的需要。DAO对象将被用来和我们的持久层沟通。我们将用Spring把业务服务对象和DAO对象连在一起。因为我们编码到接口,我们不会紧耦合实现。

The next step is to code our DAO implementation object. Since Spring has built-in support for Hibernate this example DAO will extend the HibernateDaoSupport class, which allows us to easily get a reference to a HibernateTemplate, which is a helper class that simplifies coding with a Hibernate Session and handles HibernateExceptions. Here is the interface for the DAO:

下一步是写我们的DAO实现对象。因为Spring有Hibernate内建的支持,这个例子DAO将继承HibernateDaoSupport类,它[译者注:英语语法问题:它是指“例子DAO”还是指“HibernateDaoSupport类”?]允许我们容易取得一个到HibernateTemplate的引用,HibernateTemplate是一个帮助类,它能简化Hibernate Session的编码和处理HibernateExceptions。这儿是DAO的接口:

public interface IOrderDAO {

  public abstract Order findOrderById(

                                    final int id);

  public abstract List findOrdersPlaceByUser(

                           final String placedBy);

  public abstract Order saveOrder(

                               final Order order);

}

We still have a couple more objects to wire together for our business layer. This includes the HibernateSessionFactory and a TransactionManager object. This is done directly in the Spring configuration file. Spring provides a HibernateTransactionManager, which will bind a Hibernate Session from the factory to a thread to support transactions (see ThreadLocal for more information). Here is the Spring configuration of the HibernateSessionFactory and the HibernateTransactionManager:

  我们还有两个对象要和我们的业务层连在一起。这包括HibernateSessionFactory和一个TransactionManager对象。这在Spring配置文件里直接完成。Spring提供一个HibernateTransactionManager,它将从工厂绑定一个Hibernate Session到一个线程来支持事务(见ThreadLocal获取更多的信息)。这儿是HibernateSessionFactory和HibernateTransactionManager的Spring配置。

<bean id="mySessionFactory"

       class="org.springframework.orm.hibernate.

              LocalSessionFactoryBean">

  <property name="mappingResources">

    <list>

      <value>

        com/meagle/bo/Order.hbm.xml

      </value>

      <value>

        com/meagle/bo/OrderLineItem.hbm.xml

      </value>

    </list>

  </property>

  <property name="hibernateProperties">

    <props>

      <prop key="hibernate.dialect">

        net.sf.hibernate.dialect.MySQLDialect

      </prop>

      <prop key="hibernate.show_sql">

        false

      </prop>

      <prop key="hibernate.proxool.xml">

        C:/MyWebApps/.../WEB-INF/proxool.xml

      </prop>

      <prop key="hibernate.proxool.pool_alias">

          spring

      </prop>

    </props>

  </property>

</bean>

<!-- Transaction manager for a single Hibernate

SessionFactory (alternative to JTA) -->

<bean id="myTransactionManager"

         class="org.

                springframework.

                orm.

                hibernate.

                HibernateTransactionManager">

  <property name="sessionFactory">

    <ref local="mySessionFactory"/>

  </property>

  </bean>

Each object can be referenced in the Spring configuration within a <bean> tag. In this case the bean mySessionFactory represents a HibernateSessionFactory and the bean myTransactionManager represents a Hibernate transaction manager. Notice that the transactionManger bean has a property element called sessionFactory. The HibernateTransactionManager class has a setter and getter for sessionFactory, which is used for dependency injection when the Spring container starts. The sessionFactory property references the mySessionFactory bean. These two objects will now be wired together when the Spring container initializes. This wiring relieves you from creating singleton objects and factories for referencing and creating these objects, which reduces code maintenance in your application. The mySessionFactory bean has two property elements, which translate to setters for mappingResources and hibernatePropertes. Normally, this configuration would be stored in the hibernate.cfg.xml file if you were using Hibernate outside of Spring. However, Spring provides an easy way to incorporate the Hibernate configuration within the Spring configuration file. For more information see the Spring API.

 

  每一个对象能被Spring配置里的一个<bean>标记引用。在这个例子里,bean “mySessionFactory”代表一个HibernateSessionFactory,bean “myTransactionManager”代表一个Hibernate transaction manager。注意transactionManger bean有一个叫作sessionFactory的属性元素。HibernateTransactionManager有一个为sessionFactory准备的setter和getter方法,它们是用来当Spring容器启动时的依赖注入。sessionFactory属性指的是mySessionFactory bean。这两个对象现在当Spring容器初始化时将被连在一起。这种连接把你从为引用和创建这些对象而创建singleton对象和工厂中解放出来,这减少了你的应用中的代码维护。mySessionFactory bean有两个属性元素,它们转换到为mappingResources 和 hibernatePropertes的setter方法。通常,如果你在Spring外面使用Hibernate,这个配置将被保存在hibernate.cfg.xml文件中。然而,Spring提供一个容易的方法在Spring配置文件内合并Hibernate配置。获得更多的信息看Spring API.

[注:由admin翻译上述部分2005年12月31日17:45分;由***在***修改了上述部分;由***在***修改了上述部分...请自行填写,以便联系] 

(转帖)Wiring Your Web Application with Open Source Java(1)

(由admin转自:http://www.onjava.com/pub/a/onjava/2004/04/07/wiringwebapps.html)

[译者注:欢迎大家直接在这篇译文中修改和完善,并留下你的联系方式。]

[注:这个翻译任务是从matrix的文档wiki那里看到的,我的英文水平只能勉强看懂,但是翻译它是一举三得:学技术、学英语、为网络学习作贡献,听说这篇文章在csdn上有人翻译了,可我就是没有找到,有人找到了在这里告诉一下,以免大家重复劳动。我采用从粗到精的翻译方法,先忽略细节,按我的理解粗翻一遍,然后再请大家指正,精确化细节问题。-admin ]

Tags: java spring struts hibernate programming

Bookmark with del.icio.us

 

Wiring Your Web Application with Open Source Java

by Mark Eagle

04/07/2004

用Java开源技术构建你的web应用

Building non-trivial web applications with Java is no trivial task. There are many things to consider when structuring an architecture to house an application. From a high-level, developers are faced with decisions about how they are going to construct user interfaces, where the business logic will reside, and how to persist application data. Each of these three layers has their own questions to be answered. What technologies should be implemented across each layer? How can the application be designed so that it is loosely coupled and flexible to change? Does the architecture allow layers to be replaced without affecting other layers? How will the application handle container level services such as transactions?

   创建一个不平凡的java的web应用不是一个平凡的任务,当为构建一个应用而建造一个构架时有许多问题需要考虑。从高层来说,开发者需要面对怎样构建用户界面-那里有业务逻辑在其中、和怎样持久化应用数据。这三层每一层都有它们各自的问题需要回答。跨越每一个层次什么技术应该被使用?怎样才能把程序设计得松耦合和比较容易修改?构建中一些层的替换不会影响到其它层?应用怎样处理容器级的服务,比如事务控制?

There are definitely a number of questions that need to be addressed when creating an architecture for your web application. Fortunately, there have been developers that have run into these reoccurring problems and built frameworks to address these issues. A good framework relieves developers from attempting to reinvent the wheel for complex problems; it is extensible for internal customization; and it has a strong user community to support it. Frameworks generally address one problem well. However, your application will have several layers that might require their own framework. Just solving your UI problem does not mean that you should couple your business logic and persistence logic into a UI component. For example, you should not have business logic with JDBC code inside of a controller. This is not the functionality that a controller was intended to provide. A UI controller should be a lightweight component that delegates calls to other application layers for services outside the UI scope. Good frameworks naturally form guidelines where code should be placed. More importantly, frameworks alleviate developers from building code such as persistence from scratch and allow them to concentrate on the application logic that is important to a client.

  当为你的WEB应用创建一个构架时,有相当多的问题需要考虑。幸运的是,有开发者已经冲锋陷阵到一些重复性的东西、建立框架解决这些问题。一个好的框架可以使程序员从为一个复杂应用重复发明轮子中解放出来;它应该是内核定义为可扩展的,有一个强大的用户群支持。框架通常能够很好的解决一方面的问题。然而,你的应用有许多层都需要它们各自的框架。就如解决你的用户界面并不意味着你应该把事务逻辑和持久化逻辑掺杂进你的用户界面组件。例如,你的控制器里面就不应该有包含jdbc代码的业务逻辑在里面,这不是控制器的功能。它应该是轻量级的,代理所有来自用户界面外的请求、调用其它服务这些请求的应用层。好的框架自然形成代码应该放在哪里的线索,更重要的是,框架减轻开发者写像持久层这样的代码的伤害,使他们专注于对客户来说很重要的应用逻辑。

This article will discuss how to combine several well-known frameworks to achieve loose coupling, how to structure your architecture, and how to enforce a consistent design across all application layers. The challenge is combining frameworks so that each layer is exposed to each other in a loosely coupled manner, regardless of the underlying technologies. This article will discuss one strategy for combining frameworks using three popular open source frameworks. For the presentation layer we will use Struts; for our business layer we will use Spring; and for our persistence layer we will use Hibernate. You should be able to substitute any one of these frameworks in your application and get the same effect. Figure 1 shows what this looks like from a high level when the frameworks are combined.

  这篇文章将怎样合并几个著名的框架去达成松耦合,怎样构建你的构架,怎样实施一个跨所有应用层的保持一致性的设计。挑战是合并这些框架使得每一层都以一种松耦合的方式暴露给彼此,而与底层的技术无关。这篇文章将讨论合并框架的策略使用3种流行的开源框架。表现层我们将使用Struts;业务层我们将使用Springt;持久层使用Hibrenate.你将能够在你的应用中替换这些框架中的任何一种而得到同样的效果。图1展示了当这些框架被合并时从高层看是什么样子。

Figure 1. Overview of framework architecture with Struts, Spring, and Hibernate.

图1用Struts, Spring, 和 Hibernate框架构建的概览

Application Layering

Most non-trivial web applications can be divided into at least four layers of responsibility. These layers are the presentation, persistence, business, and domain model layers. Each layer has a distinct responsibility in the application and should not mix functionality with other layers. Each application layer should be isolated from other layers but allow an interface for communication between them. Let's start by inspecting each of these layers and discuss what these layers should provide and what they should not provide.

应用的分层

大多数不平凡的web就用能被分成至少4个各负其责的层次。这些层次是:表现层、持久层、业务层、领域模型层。每层在就用中有分别的责任,不会和其它层混淆功能。每一应用层应该彼此独立但是在它们之间允许一个接口互相交流。让我们开始深入每一层和讨论这些层应该提供什么和不应该提供什么。

The Presentation Layer

表现层

[下面是卖书的广告]

Related Reading

 

Hibernate: A Developer's Notebook

By James Elliott

Table of Contents

Index

Sample Chapter

Read Online--Safari Search this book on Safari:

    

 Only This Book All of Safari

Code Fragments only

[/广告结束]

 

At one end of a typical web application is the presentation layer. Many Java developers understand what Struts provides. However, too often, coupled code such as business logic is placed into an org.apache.struts.Action. So, let's agree on what a framework like Struts should provide. Here is what Struts is responsible for:

  在一个典型的web应用的一端是表现层。许多java程序员懂得Struts提供什么。然而,太多的人把像业务逻辑之类的耦合的代码放进了一个org.apache.struts.Action。所以,让我们在像Struts这样一个框架应该提供什么上取得一致意见。这儿是Struts负责的:

Managing requests and responses for a user.

Providing a controller to delegate calls to business logic and other upstream processes.

Handling exceptions from other tiers that throw exceptions to a Struts Action.

Assembling a model that can be presented in a view.

Performing UI validation.

为用户管理请求和回应;

提供一个控制器代理业务逻辑调用和其它上游的处理;

处理从其它层掷出给一个Struts Action的异常;

装配一个能被呈现进一个视图的模型;

执行用户界面验证。

Here are some items that are often coded using Struts but should not be associated with the presentation layer:

Direct communication with the database, such as JDBC calls.

Business logic and validation related to your application.

Transaction management.

Introducing this type of code in the presentation layer leads to type coupling and cumbersome maintenance.

这儿是一些经常被使用Struts编写的而不应该和表现层相伴的项目:

直接和数据库沟通,比如JDBC调用;

业务逻辑和与你的应用相关的验证;

传输管理;在表现层中引入这种代码将导致类型耦合和讨厌的维护。

The Persistence Layer

At the other end of a typical web application is the persistence layer. This is usually where things get out of control fast. Developers underestimate the challenges in building their own persistence frameworks. A custom, in-house persistence layer not only requires a great amount of development time, but also often lacks functionality and becomes unmanageable. There are several open source object-to-relational mapping (ORM) frameworks that solve much of this problem. In particular, the Hibernate framework allows object-to-relational persistence and query service for Java. Hibernate has a medium learning curve for Java developers who are already familiar with SQL and the JDBC API. Hibernate persistent objects are based on plain-old Java objects and Java collections. Furthermore, using Hibernate does not interfere with your IDE. The following list contains the type of code that you would write inside a persistence framework:

持久层

在典型web应用的另一端是持久层。这通常是使事情很容易失控的地方。开发者低估了建造他们自己的持久层框架的挑战性。机构内部自己写的持久层不仅需要大量的开发时间,而且缺少功能和变得难以控制。有几个开源的“对象-关系映射”(ORM)框架非常解决问题。尤其是,Hibernate框架允许“对象-关系持久化”和Java查询服务。Hibernate对那些已经熟悉了SQL和JDBC API的Java开发者有一个适中的学习曲线。Hibernate持久对象是基于简单的老的Java对象和Java集合。此外,使用Hibernate不会被你的IDE干扰。下面的列表包含了将写在一个持久层框架里的代码类型:

[注:由admin翻译上述部分2005年12月28日22:40分;由***在***修改了上述部分;由***在***修改了上述部分...请自行填写,以便联系]

Querying relational information into objects. Hibernate does this through an OO query language called HQL, or by using an expressive criteria API. HQL is very similar to SQL except you use objects instead of tables and fields instead of columns. There are some new specific HQL language elements to learn; however, they are easy to understand and well documented. HQL is a natural language to use for querying objects that require a small learning curve.

查询相关的信息成为对象。Hibernate通过一种叫作HQL的面向对象的查询语言或者使用条件表达式API来做这个事情。HQL除了使用对象代替表、使用字段代替列外和SQL非常相似。有一些新的特殊的HQL语言元素要学;但是,它们非常容易理解和良好的文档化。HQL是一种使用来查询对象的自然语言,需要很小型的学习曲线。

Saving, updating, and deleting information stored in a database.

保存、更新、删除储存在数据库中的信息。

Advanced object-to-relational mapping frameworks like Hibernate have support for most major SQL databases, and they support parent/child relationships, transactions, inheritance, and polymorphism.

像Hibernate这样的高级“对象-关系”映射框架提供对大多数主流SQL数据库的支持,它们支持“父/子”关系、事务、继承和多态。

Here are some items that should be avoided in the persistence layer:

这儿是一些应该在持久里被避免的项目:

Business logic should be in a higher layer of your application. Only data access operations should be permitted.

业务逻辑应该在你的应用的一个高一些的层次里。持久层里仅仅允许数据存取操作。

You should not have persistence logic coupled with your presentation logic. Avoid logic in presentation components such as JSPs or servlet-based classes that communicate with data access directly. By isolating persistence logic into its own layer, the application becomes flexible to change without affecting code in other layers. For example, Hibernate could be replaced with another persistence framework or API without modification to the code in any other layer.

你不应该有持久层逻辑和你的表现层逻辑搅在一起。避免像JSPs或基于servlet的类这些在表现层里的逻辑和数据访问直接交流。靠把持久层逻辑隔离进它自己的层,应用变得易于修改而不会影响在其它层的代码。例如:Hebernate能够被其它持久层框架或者API代替而不会修改在其它任何层的代码。

The Business Layer

The middle component of a typical web application is the business or service layer. This service layer is often the most ignored layer from a coding perspective. It is not uncommon to find this type of code scattered around in the UI layer or in the persistence layer. This is not the correct place because it leads to tightly coupled applications and code that can be hard to maintain over time. Fortunately, several frameworks exist that address these issues. Two of the most popular frameworks in this space are Spring and PicoContainer. These are referred to as microcontainers that have a very small footprint and determine how you wire your objects together. Both of these frameworks work on a simple concept of dependency injection (also known as inversion of control). This article will focus on Spring's use of setter injection through bean properties for named configuration parameters. Spring also allows a sophisticated form of constructor injection as an alternative to setter injection as well. The objects are wired together by a simple XML file that contains references to objects such as the transaction management handler, object factories, service objects that contain business logic, and data access objects (DAO).

[注:糟糕,还没有接触过Spring和PicoContainer,这下面的翻译肯定是漏洞百出,还望大虾不吝赐教:)]

业务层

在一个典型的web应用的中间的组件是业务层或服务层。这个服务层从编码的角度是经常最容易被忽略的层。不难在用户界面层或者持久层里找到散布在其中的这种类型的代码。这不是正确的地方,因为这导致了紧耦合的应用和代码,有时难以维护。幸运的是,几个存在的框架征对这些问题。在这个领域两个最流行的框架是Spring和PicoContainer.这些叫作微容器,你可以不费力不费神的把你的对象连在一起。所有这些框架都工作在一个简单的叫作“依赖注入”(也通称“控制反转”)的概念上。这篇文章将着眼于Spring的为指定的配置参数通过bean属性的setter注入的使用。Spring也允许一个构建器注入的复杂形式作为setter注入的一个替代。对象们被一个简单的XML文件连在一起,这个XML文件包含到像事务管理器、对象工厂、包含业务逻辑的服务对象、和数据存取对象(DAO)这些对象的引用。

The way Spring uses these concepts will be made clearer with examples later in this article. The business layer should be responsible for the following:

Handling application business logic and business validation

Managing transactions

Allowing interfaces for interaction with other layers

Managing dependencies between business level objects

Adding flexibility between the presentation and the persistence layer so they do not directly communicate with each other

Exposing a context to the business layer from the presentation layer to obtain business services

Managing implementations from the business logic to the persistence layer

Spring使用这些概念的方法在这本书将在后面用例子说得更清楚一些。业务层应该负责下面这些事情:

处理应用业务逻辑和业务验证;

管理事务;

允许界面和其它层交互;

管理业务层对象之间的依赖;

增加在表现层和持久层之间的灵活性,使它们彼此不直接相互沟通;

从表现层暴露一个上下文给业务层获得业务服务;

管理从业务逻辑到持久层的实现。

The Domain Model Layer

Finally, since we are addressing non-trivial, web-based applications we need a set of objects that can move between the different layers. The domain object layer consists of objects that represent real-world business objects such as an Order, OrderLineItem, Product, and so on. This layer allows developers to stop building and maintaining unnecessary data transfer objects, or DTOs, to match their domain objects. For example, Hibernate allows you to read database information into an object graph of domain objects, so that you can present it to your UI layer in a disconnected manner. Those objects can be updated and sent back across to the persistence layer and updated within the database. Furthermore, you do not have to transform objects into DTOs, which can get lost in translation as they are moved between different application layers. This model allows Java developers to work with objects naturally in an OO fashion without additional coding.

领域模型层

最后,因为我们讨论不平凡的、基于web的应用,我们需要一组对象能在不同的层之间移动。领域对象层由那些代表真实世界业务对象,比如:一份订单、订单项、产品等等组成。这个层允许开发者停止建造和维护不必要的数据传输对象,或者DTOs,来匹配他们的领域对象。例如,Hibernate允许你把数据库信息读进领域对象的一个对象图,所以你能以一种分离的方式把它交给你的用户界面层。那些对象能被更新和送回到持久层在数据库里更新。进一步,你不必转换对象到DTOs,DTOs能在传输中迷路,因为他们在不同的应用层间移动。这种模式允许Java开发者自然地以一种面向对象的风格和对象一起工作,没有附加的编码。

[注:由admin翻译上述部分2005年12月30日20:57分;由***在***修改了上述部分;由***在***修改了上述部分...请自行填写,以便联系]

大家都来做翻译

  看到好的英文文章,想把翻译成中文吗?

  看不懂好的英文文章,想得到它的中文翻译吗?

  这个目标提供给大家做翻译练习。大家都用guest帐号登录,都可以在上面写,你可以在其中写上你的联系方式和你在学习日记的注册帐号。

  简单的说,这就是尝试一个最简单的Wiki。

  每篇翻译就是一篇日记。

(转帖)web中下拉列表的几种实现

转自:http://www.matrix.org.cn/resource/article/43/43809.html

Matrix首页 Java文栏 业界新闻 部落格 资源下载 Java 论坛 web中下拉列表的几种实现

wldandan 发表于2005-09-23 作者:wldandan 评价:0/0 评论数:4 点击数:1490 [收藏]

摘要:

总结一下关于web上使用下拉框的情况

本文Matrix永久镜像:http://www.matrix.org.cn/resource/article/43/43809.html

说明:本文可能由Matrix原创,也可能由Matrix的会员整理,或者由

Matrix的Crawler在全球知名Java或者其他技术相关站点抓取并永久

保留镜像,Matrix会保留所有原来的出处URL,并在显著地方作出说明,

如果你发觉出处URL有误,请联系Matrix改正.

总结一下关于web上使用下拉框的情况

从数据库中获得数据List,将数据放到Request里面

        使用setAttribute(”AList”,AList)

A中有2个属性(String id,String value)

1.        使用JSTL的forEach方式

<select name=”xx” ……..>

<c:forEach items="${AList}" var="p" >

        <c:choose>

                <c:when test="${xxx == p.id}">

                        <option value='<c:out value="${p.id}"/>' selected="selected">

                                        <c:out value="${p.value}"/>

                        </option>

                </c:when>

        <c:otherwise>

                        <option value='<c:out value="${p.id}"/>'>

                                <c:out value="${p.value}"/>

                        </option>

                </c:otherwise>

        </c:choose>       

<c:forEach>

</select>

2.        使用struts的标签

<html:select property=”xxx”>

<html:options collection="AList" labelProperty="value" property="id" />

</html:select>

查一下struts的api文档,可以看到select 中选项有3 taglib可以使用。

第一种直接使用把所有选项写在中间。

<html:option value="0-15">0-15</html:option> <html:option value="15-20" >15-20</html:option> <html:option value="20-30" >20-30</html:option> <html:option value="20 or above">30 or above</html:option>

第二种:把选项放在一个Collection中(这里使用List).在实际项目中,更多的是可能数据来源于db,文件等。这种情况用得比较多。

<html:options collection="AList" property="value" labelProperty="label"/>把option放在list中的过程在Action中作处理//prepare the age selector list.List ageList =new ArrayList();ageList.add(new LabelValueBean("0-15","0-15"));ageList.add(new LabelValueBean("15-20","15-20"));ageList.add(new LabelValueBean("20-30","20-30"));ageList.add(new LabelValueBean("30 or above","30 or above"));request.setAttribute("AList",AList);

这里使用了LabelValueBean,可以不用的,象

<html:options collection="AList" labelProperty="value" property="id" />

只要在AList中填入的bean有value和id属性就可以

第三种,把此list 作为Form 的一个属性.

<html:optionsCollection property="AList" />

在Form 中添加AList 的setter和getter. Form中作如下处理。

//the list can be a form property.

f.setAgeList(AList);

1.        从数据库中获得数据,你应该在Action里面取得数据后,将数据放到Request里面

2.        数据取出来后放在一个List或Collection或Map里面,我习惯用List

3.        从List或其它的容器中取数据应该用<html:options> 或<html:optionsCollection>

4.        <html:options> 和<html:optionsCollection>外层必须用<html:select property="">,所以这个属性你必须在FormBean里定义

5.        由于你要用到这些标签,所以你必须定义FormBean

6.       

从Action取数据,以List为例

List list = xxxxx;//从数据库中取得下拉列表中的数据

request.setAttribute("list",list);

在页面显示

<html:form action="xxxx">...<html:select property="xxx"><html:options collection="list" labelProperty="下拉框中显示的内容,一般是name或其它相似属性" property="各选项对应的值,一般是id" /></html:select>...</html:form>

补充一点点:

因为数据你要从 数据库去取, 所以一般在 action 里调用 DAO ,作为 request 的一个属性传到页面上; 这时一般用 <html:options .../> 标签

另外,如果数据不从数据库去取,而是代码固定的,则一般把这种放到 ActionForm 里,作为属性在页面上取,这时一般用 <html:optionsCollection ... />

我来评价此文: 非常好 还行 一般 扔鸡蛋 总得分:0 投票人次:0

→用户评论列表

#7269 评论作者: littlebat 发表时间:2005-12-27 10:34

正准备用它,对于我来说,上面的信息足够了。谢谢。

#6861 评论作者: jctr 发表时间:2005-12-09 03:59

还应该有第三种,Tapestry的实现,其实也不只这三种还有很多很多吧

#5288 评论作者:xuerldx 发表时间:2005-10-25 07:37

还是不错,就是 有点肤浅

#4811 评论作者: highfan 发表时间:2005-10-05 04:46

你可以把collection 作为

actionform 的

一个属性,在 actionform 中 初始化 也可以 ,在 action 中

初始化 也可以。这样更简单。同时减少view和 control 直接的命名依赖。

我们可以在一张活动图上画一个用例和用例的所有扩展

  今天,向umlchina讨论组和argouml用户讨论组发了一封信,请教是否可以在一张活动图上画一个用例和用例的所有扩展。很高兴收到了argouml开发者mvw的回复。他的意见是可以这样做,并且详细解释了用例图中“包括”和“扩展”的关系。从中可以看出argouml开发社区对用户的真诚和友好。这愈发坚定了我使用argouml进行设计的决心。

  附我的信件和mvw的回信:

From: "Michiel van der Wulp" <mvw@tigris.org>  Add to Address Book  Add Mobile Alert 

To: users@argouml.tigris.org

Date: Tue, 27 Dec 2005 09:28:35 +0100

Subject:  Re: [argouml-users] A question about drawing activity diagram for extends usecases

   

Hi Dashing,

 

Nice colourful diagrams!

 

>> Can I draw the activty diagrams of a usecase and

>> all its extends usecase in one activity diagram?

 

Yes. Since the extends are steps that only happen conditionally, it would be nice to show the condition in the diagram, too. You already did this in the other activity diagram in two ways: with a Junction state (the diamond), and with a Guard - I think both are OK. The junction slightly preferred if people that only know flow-charts have to read the diagrams.

 

One other remark on usecases, which seem to be confused by many, is the difference between include and extend.

An include is comparable with a subroutine: it is always executed, and (usually) only pulled out from the main usecase because it is common with other usecases. An extension is something that happens on a condition somewhere along the path.

 

Regards,

Michiel

 

----- Original Message -----

From: Dashing Meng

To: umlchina@yahoogroups.com ; users@argouml.tigris.org ; 炜 张

Sent: Tuesday, December 27, 2005 4:40 AM

Subject: [argouml-users] A question about drawing activity diagram for extends usecases

Hi,

  Can I draw the activty diagrams of a usecase and all its extends usecase in one activity diagram?here is my usecase diagram:

http://www.learndiary.com/pictures/easyDiary/easyDiaryUseCaseDiagram.gif

this is my activty diagram:

http://www.learndiary.com/pictures/easyDiary/PostADiaryactivityDiagram.gif

my unfinished ArgoUML0.18.1 model:

http://www.learndiary.com/pictures/easyDiary/easyDiary.zargo

 

thanks a lot.

搞不懂ultraEdit的汉字编码问题了

用ultraEdit8英文版,在它和eclipse之间复制汉字会成乱码,直接在各自的窗口中编辑同一个文件,不会成乱码;

用ultraEdit11中文版,eclipse用GBK默认保存的汉字,用它打开成乱码。用它编写的汉字保存后,在eclipse中成乱码,在编译后的程序中成乱码。

真是搞不懂了,只有不用ultraEdit11了,使用ultraEDIT8也不要使用粘贴复制功能了。