更新:
我有一个桌面应用程序,以下组件进行交互:
如果控制器要求服务执行某些操作,但该服务首先需要来自控制器的更多内容(即控制器必须使用UI从用户获取的数据),服务如何获取控制器这样做?
我很满意
的概念等等。
但是,关于Controller与服务通信,最适合的方法是什么?应:
我喜欢第一个选项,因为第二个选项可能意味着类爆炸,每个Service方法需要一个ServiceResult
- 样式类。
我问,因为服务组件当然无法告诉用户界面该怎么做,只有控制器可以,但是控制器不知道如何告诉用户界面而不从服务获得一些反馈。
您怎么看?
答案 0 :(得分:2)
在设计服务层/类时,首先要记住的是使它们具有高度可重用性。它们应该是原子服务对象,不仅可以为您的控制器服务,还可以为将来的任何其他客户端服务。
这里有几个问题:
控制器如何找到服务?
如果您希望拥有高度可重用,可扩展和...服务对象,则控制器和服务类之间的依赖关系应该是松散耦合的。避免任何紧耦合技术。相反,尝试将inject服务类添加到控制器(使用IOC容器),也可以使用Service Locator Design Pattern。
如何与服务沟通?
嗯,这取决于您的应用程序的大小。您可以使用企业服务技术,例如Web服务,只需使用应用程序服务。基于此,您可以在控制器和服务之间定义协议。
服务应该返回控制器的数据是什么? 请记住,服务层不应该知道有关UI导航的任何信息。控制器有责任根据服务对象的响应来决定去哪里以及做什么。为什么?想象一下,这个服务类需要用于另一个UI(比如从web到flex,silverlight或桌面应用程序)。如果在服务类中添加导航逻辑(作为一个极端的例子,UI逻辑/格式化),它将无法重用于另一个UI系统,并且即使在同一个应用程序中的其他服务类和控制器也不可重用
底线,尝试保持服务类清除任何导航逻辑。控制器真正用于此目的。
答案 1 :(得分:2)
您最好的选择可能是使用事件或委托模型 - 例如,控制器订阅“需要更多信息”事件并显示相应的表单。将附加数据返回给服务可以通过几种不同的方式完成,但在很大程度上取决于您的设计细节(例如,您的服务是无状态等)
您是否为自己的服务编写过单元测试?如果没有,这个过程可能会帮助您澄清您的设计需求。
答案 2 :(得分:0)
请参阅我的问题here
有一些缺失的细节可以更好地回答你的问题:
是网络还是桌面方案?
如果桌面 - 它是断开连接的场景吗? (例如,具有远程服务的富客户端)或客户端和服务是否在同一台机器上?
如果是网络 - 它是经典的Web 1.0应用程序吗? (视图是作为页面创建的)还是富客户端? (AJAX,Flex,SilverLight)控制器有时可以在客户端? (柔性)
所有这些都会对决策产生重大影响。
顺便说一下,你是否有意省略了模型?
答案 3 :(得分:0)
我在MVC上工作很多(虽然我的是Java Web应用程序的味道),我经常偶然发现一些情况,似乎服务需要以某种方式与控制器进一步交互。但是在每种情况下,结果都表明我在控制器中做错了什么,或者我的服务接口不够灵活(即,细粒度)。
当服务没有收到足够的数据时,这是由于用户提供的无效输入吗?如果是,则控制器应对输入执行验证并显示相应的提示或错误消息。
如果预计用户不会立即提供所有数据,那么控制器应该知道该服务不会按原样接受数据。因此,控制器应该通过UI管理与用户的对话,最后最终将所有内容传递给服务。
或许控制器需要在整个向导流程中查询服务。在这种情况下,服务的界面可能应该更精细。
我会选择你提出的选项#1。如果控制器能够从UI收集所有必需的输入并将它们提供给服务,但是它无法执行此操作,那么服务应该抛出异常。使用异常是明智的,因为您试图将无效数据传递给服务。 (这并没有改变以下事实:不应该抛出异常来控制程序流,而是指示控制器实际上已经搞砸了为服务提供一些无效数据。)
答案 4 :(得分:0)
您是否考虑过使用Model View Presenter?
您的UI视图将实现接口,这些接口将为您的服务所知。这样,您的服务可以调用UI来请求更多信息来执行他们的任务。这是一种dependency inversion (pdf)。