在Craig Larman的书Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development (3rd Edition)中,用例被转换为包含系统操作的系统序列图(SSD)。这是一种先进行高级设计的方法,可以轻松追溯到需求(用例),然后通过OO设计原则详细说明域级别的系统操作来进行精炼。
我正在尝试使用RESTful服务来理解这种方法。问题似乎与资源和无状态操作有关。
以下是本书中的一个示例,一个具有四个系统操作的SSD:
SSD也是表示层(左侧)和域层(右侧)的抽象。域层还可以包括应用程序和/或业务逻辑。
在Larman的方法中,系统操作(例如,makeNewSale()
)应由GRASP Controller处理,Byte Rot blog by Aliostad是处理系统的域非表示层对象操作。
现在,假设我们尝试在这种方法中使用RESTful服务:
http://...com/sales - POST request
,最终GRASP控制器会收到makeNewSale()
。 REST部分http://...com/sales - POST request
为销售创建新资源,例如,001
并且makeNewSale()
也被发送到GRASP控制器对象。
makeNewSale()
可能需要接收和处理身份验证令牌作为参数,因为:System
没有会话信息。我在How to manage state in REST 所以,假设我的理解到现在为止,我的问题是:
REST的统一接口约束是否尊重表示/域层分离的松散耦合?起初,它似乎是表示层的细节(就像Java Swing中的actionPerformed()
方法)。但困扰我的部分是http://...com/sales
绑定到Sale
(域)对象。
另一种方式:通过创建REST资源和REST通过统一接口访问它们的动词是不是将应用程序/业务逻辑放入表示层? Larman的SSD方法是关于层的,他明确指出应用程序逻辑不应该进入表示层。例如,对http://...com/sales
的POST会创建新的sales/001
资源,并发送makeNewSale()
。第一部分看起来像商业逻辑。我的REST资源名称遵循我的许多Domain对象名称的事实似乎我的表示层(更多)耦合到我的域层,而不是我使用Swing并且仅从makeNewSale()
调用actionPerformed()
在JButton
上。
Larman的SSD概念面向RCP模型(服务器中具有状态),但是可以通过REST理念轻松实现SSD吗?例如,存在endSale()
以将系统从enterItem()
调用循环中分离出来。在本书的后面,拉曼甚至提出了一个关于此的状态图:
我读到了{{3}},如果需要,似乎必须注意在每个系统操作上传递状态(如上面的身份验证令牌示例),或者“状态”实际上封装在资源中。我考虑过它,使用REST,endSale()
可能会被完全删除。
我在这里使用了一个具体的例子,所以答案也可以是具体的。
答案 0 :(得分:1)
我会尝试解决你的问题,但请记住,这是一个非常有争议的话题。
REST统一接口确实尊重表示和业务逻辑之间的关注点分离。分离是关于表示层不知道关于业务逻辑的实现的细节,反之亦然,但是没有必要隐藏可以对域实体(即可用于资源的服务)做什么。您要隐藏的是如何执行操作。
REST的HATEOAS原则规定资源的表示(域实体的实例)应该封装客户端/服务器交互的状态,因此服务应该以某种方式将该状态返回给客户端。这个,以及超媒体的使用(即指向可用服务的链接 - 表示可以在资源上执行的动作,给定其状态)应该很容易地映射到您发布的状态图。
让我们继续你的例子:
假设有一个服务newSale
返回Sale
个对象。必须使用POST
方法调用此服务。在Sale
的{{1}}部分,有2个链接,一个链接到hypermedia
服务(也是addItem
,并接受POST
的更新版本} object,保存后返回它,以及Sale
服务(也是endSale
),保存POST
并将其标记为“完成”。最后一个服务不返回任何资源表示,只有http响应OK如果成功保存对象。