最近我一直在反射(reflection)我的 android architecture project ,试图让它适应更“干净的架构”,特别是那种设计 suggested by “Uncle Bob” .
它涉及多个抽象层,很好的职责隔离和通过依赖注入(inject)实现的非常强的依赖倒置;这最终导致了一个非常解耦的可移植系统。通过单元测试和集成测试进行测试的完美候选者。
在我的 android 实现中,我最终拥有三个不同的模块或层:
- 域 :实体、交互者、演示者 (纯java模块)
- 数据 :(充当向域提供数据的存储库) (android 库模块)
- 演示文稿 : ui 相关的东西、 fragment 、 Activity 、 View 等 (安卓应用模块)
所以,我试图找出 iOS 生态系统中最好的方法。
我尝试创建一个具有多个目标的项目来实现相同的解决方案:
- 域 :命令行目标 (这看起来很奇怪,但我认为这是可用的最纯粹的 swift 目标)
- 数据 : cocoa touch 框架
- 演示文稿 : cocoa touch 框架
通过这种方法,我可以像使用 android 模块一样使用这些目标。但是我发现的第一个警告是我需要手动将每个新文件添加到依赖目标。
但是我对具有多个目标的项目的了解非常有限。我的意思是我从未创建过具有多个目标的 iOS 应用程序。所以我不知道该解决方案是否会使用框架(cocoa touch/cocoa)作为目标,而不是域层的命令行模块。
任何想法都会非常感激。
谢谢!
最佳答案
Uncle Bob 的 Clean Architecture 绝对适用于 iOS、Swift 和 Obj-C。架构与语言无关。 Bob 叔叔自己主要用 Java 编写代码,但在他的演讲中他很少提到 Java。他的所有幻灯片甚至都没有显示任何代码。它是一种适用于任何项目的架构。
为什么我这么确定?因为我已经研究了 2 年的 MVC、MVVM、ReactiveCocoa 和 Clean Architecture。到目前为止,我最喜欢 Clean Architecture。我通过将 7 个 Apple 示例项目转换为使用 Clean Architecture 来测试它。我已经专门使用这种方法一年多了。每次都效果更好。
一些好处是:
doSomethingOnLoad()方法不是边界方法。相反,它是一个仅在 CreateOrderViewController 内调用的内部方法。 .在单元测试中,我们测试单元的预期行为。我们给出输入,观察输出,然后将输出与我们的期望进行比较。doSomethingOnLoad()一种私有(private)方法。但我选择不这样做。 Swift 的目标之一是让开发人员更容易编写代码。所有边界方法都已在输入和输出协议(protocol)中列出。真的没有必要用无关的私有(private)修饰符乱扔类。CreateOrderViewController 应该使用此请求数据在加载时执行某些操作”的行为,对吗?如果我们不能调用 doSomethingOnLoad() 我们如何测试这个因为它是一个私有(private)方法?您拨打 viewDidLoad() . viewDidLoad()方法是一种边界方法。哪个境界?用户和 View Controller 之间的边界!用户对设备做了一些事情以使其加载另一个屏幕。那么我们如何调用viewDidLoad()然后?你这样做:let bundle = NSBundle(forClass: self.dynamicType)
let storyboard = UIStoryboard(name: "Main", bundle: bundle)
let createOrderViewController = storyboard.instantiateViewControllerWithIdentifier("CreateOrderViewController") as! CreateOrderViewController
let view = createOrderViewController.view
createOrderViewController.view属性会导致 viewDidLoad()被调用。我很久以前从某人那里学到了这个技巧。但是Natasha The Robot最近也提到过。CreateOrderRequest ,先问是否doSomethingOnLoad()是您应该为其编写测试的边界方法。如果不是,那是什么?边界法其实是viewDidLoad()在这种情况下。输入是“当这个 View 加载时”。输出是“用这个请求对象调用这个方法”。CreateOrderViewControllerInput 下。和 CreateOrderViewControllerOutput .你不需要去别处寻找!doSomethingOnLoad() .您模拟请求对象,然后断言它等于您预期的请求对象。你在 mock 某事并比较它。就像 assert(1, 1)而不是 var a=1; assert(a, 1) .重点是什么?太许多 测试。太易碎 .CreateOrderRequest .在您验证正确后 CreateOrderRequest可以由 View Controller 组件生成。测试时 CreateOrderInteractor的 doSomething()边界方法,然后你模拟 CreateOrderRequest使用接口(interface)依赖注入(inject)。关于android - 尝试在 iOS 应用程序上安装 "clean architecture",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32201661/
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou
我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-
对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl
我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.
我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
我想用ruby编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序
为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar
我打算为ruby脚本创建一个安装程序,但我希望能够确保机器安装了RVM。有没有一种方法可以完全离线安装RVM并且不引人注目(通过不引人注目,就像创建一个可以做所有事情的脚本而不是要求用户向他们的bash_profile或bashrc添加一些东西)我不是要脚本本身,只是一个关于如何走这条路的快速指针(如果可能的话)。我们还研究了这个很有帮助的问题:RVM-isthereawayforsimpleofflineinstall?但有点误导,因为答案只向我们展示了如何离线在RVM中安装ruby。我们需要能够离线安装RVM本身,并查看脚本https://raw.github.com/wayn