TLDR: Writing a service (in the model layer). It talks to ffmpeg. Where should validation go? Should I create a service response object so it is testable? How should it be structured?
Background: I'm designing some classes to retrieve data from an external service. It could be an API, but in fact it's calls to ffmpeg cli, which in effect is an API to the conversion tools themselves.
当与外部服务对话时,检索到的数据可能并不总是相同的,如何最好地在您的一端至少保持一致的应用程序状态,以便您的应用程序不依赖于外部服务来执行工作?
到目前为止,我已经分离出类,试图维护 SRP其中:
class CommandDispatcher { }
Command Dispatcher 的唯一工作是发出数据请求(到 ffmpeg)并检索该数据的响应。
class Converter { }
转换器的唯一职责是接受用户请求(例如将 1 转换为 2),并将基础知识发送到处理 exec() 调用的命令调度程序。
这是我的问题:
APIRequest 和一个 APIResponse 对象(在本例中是一个 FFmpegResponse 对象)?我已经看到 OAuth 的例子,其中有一个 OAuth 响应对象。然而,这很简单,因为对此的调用是通过 HTTP 协议(protocol)完成的,该协议(protocol)往往至少会返回一个错误代码和一条消息。调用 ffmpeg 之类的东西并不能保证类似的响应(例如,可能未安装 ffmpeg)。这个对象仅仅是一个域对象(即一个实体:一些类成员和 setter 和 getter)吗?
FFmpegResponse 对象,谁的工作是将数据放入 Response 对象的正确成员中?假设未安装 ffmpeg,CommandDispatcher 返回的响应为空。是否由 CommandDispatcher 来填充 FFmpegResponse 对象并显示“未安装 ffmpeg”错误?我应该让验证对象执行此操作吗?
请记住,我在这里试图坚持单一职责原则,所以我认为 CommandDispatcher 不应该关心数据是否有效 - 它应该只是询问获取数据并检索它。我的验证适合此服务的模型层中的什么位置?
这不仅适用于 FFmpeg,而且有助于将来的外部服务调用。无论外部服务是否以预期方式响应,构建代码和类以维护 SRP 和一致的应用程序状态的最佳[实践]方法是什么?
最佳答案
在您当前的结构中,CommandDispatcher 应该是接口(interface)或抽象类(取决于抽象代码的必要性)。然后,您将创建一个具体的实现:FFMpegCommandDispatcher,它将封装对 ffmpeg 特定响应的理解。
响应对象将采用类似的结构:CommandResponse 将是具有具体实现的抽象 FFMpegCommandResponse。
最好创建一组常见错误条件(serviceNotAvailable、serviceNotInstalled、serviceDiedAHorribleAndBloodyDeath 等)。然后,您的调度程序实现可以在响应对象和提供者实现特定细节上设置一个常见错误代码。 ('错误 1984: FFMpeg 正在监视你')
如果您也担心(我也会担心)验证输入。您可以创建一个 CommandRequest 抽象和 FFMpegRequest 实现,它将接收用户输入并确保可以将其发送到命令行。
关于php - 外部服务/API请求和响应的抽象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20517398/
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru
在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo
我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie
我有用于控制用户任务的Rails5API项目,我有以下错误,但并非总是针对相同的Controller和路由。ActionController::RoutingError:uninitializedconstantApi::V1::ApiController我向您描述了一些我的项目,以更详细地解释错误。应用结构路线scopemodule:'api'donamespace:v1do#=>Loginroutesscopemodule:'login'domatch'login',to:'sessions#login',as:'login',via::postend#=>Teamroutessc
我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b
您如何在Rails中的实时服务器上进行有效调试,无论是在测试版/生产服务器上?我试过直接在服务器上修改文件,然后重启应用,但是修改好像没有生效,或者需要很长时间(缓存?)我也试过在本地做“脚本/服务器生产”,但是那很慢另一种选择是编码和部署,但效率很低。有人对他们如何有效地做到这一点有任何见解吗? 最佳答案 我会回答你的问题,即使我不同意这种热修补服务器代码的方式:)首先,你真的确定你已经重启了服务器吗?您可以通过跟踪日志文件来检查它。您更改的代码显示的View可能会被缓存。缓存页面位于tmp/cache文件夹下。您可以尝试手动删除
在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList()Obt
我正在使用Mandrill的RubyAPIGem并使用以下简单的测试模板:testastic按照Heroku指南中的示例,我有以下Ruby代码:require'mandrill'm=Mandrill::API.newrendered=m.templates.render'test-template',[{:header=>'someheadertext',:main_section=>'Themaincontentblock',:footer=>'asdf'}]mail(:to=>"JaysonLane",:subject=>"TestEmail")do|format|format.h