RxSwift 和控制流 - 一个坏主意?

Posted

技术标签:

【中文标题】RxSwift 和控制流 - 一个坏主意?【英文标题】:RxSwift and control flow - a bad idea? 【发布时间】:2018-04-16 20:55:24 【问题描述】:

我开发了一个结构,可以在我的应用程序中生成随机数据用于测试目的,但只有在 Realm 数据库为空时才会这样做。负责 CRUD 操作的服务类将结果/结果作为 RxSwift Observables 返回。 生成新数据取决于 Realm 的内容 - 使用 guard 是合乎逻辑的选择,但需要向返回 Int 而不是 Observable 的服务添加一个新方法,这似乎是不必要的代码重复和有点不一致。

class Service 
  let realm = try! Realm()
  ...
  // Existing reactive code
  func patients() -> Observable<Result<Patient>> 
    let results = realm.objects(Patient.self)
    return Observable.collection(from: results)
  

  func objectCount() -> Int 
    let realm = try! Realm()
    return realm.objects(Patient.self).count
  


struct DataGenerator() 
...
  func createRandomPatients() 
    let service = Service()
    guard service.objectCount() == 0 else  return 
    ...
    //go on to generate patients

我能想到使用响应式服务方法复制此控制流的唯一方法是将Observable 绑定到Variable

... service code as above ...
func createRandomPatients() 
   let isEmpty = Variable<Bool>(false)
   service.patients().map $0 == 0 .bind(to: isEmpty)
   guard isEmpty.value else  return 
   // etc

这似乎有点儿糊涂,因为它可能不是很清楚,但它避免了将不会在生产应用程序中使用的代码添加到服务类中。这是不好的做法还是只是个人喜好?如果有人有替代解决方案,我愿意接受...

【问题讨论】:

【参考方案1】:

Faking绝对是应该用多态来处理的。

一个好的设计是定义一个通用接口;例如可以是PatientsSource:

protocol PatientsSource 

    func patients() -> Observable<Result<[Patient]>>


你可以通过定义来利用多态性:

class PatientsService: PatientsSource... 
    //w/e


struct FakePatients: PatientsSource 
    //your random patients generation

如果您使用Service 样式架构,那么您应该将ServicePatientsSource 分别传递给用户(如您的控制器),即使它们最终可能是同一个对象。

【讨论】:

一个好点,而且,碰巧,我有 50% 在那里,因为 PatientService 实际上是基于一个协议 (PatientServiceType) 所以伪造/模拟是我的待办事项重构列表中的东西。不过对控制流问题有什么想法吗? @rustproofFish 我完全误读了你的问题,但现在我有点难以理解问题所在。你能提供更多关于你打电话给createRandomPatients()的信息吗?我觉得控制流问题可以用Refreshable装饰器***.com/questions/47031210/rxswift-reload-tableview/…之类的东西来解决 @rustproofFish 和guard 语句听起来应该是filterpatients 链的一部分。这是 UI 要求吗? 很抱歉给您带来了困惑。我提供的示例实际上是伪代码,因为我的应用程序使用了很多协议,列出完整代码会有点混乱。 PatientService 使用 RxSwift 以反应方式向应用程序的其余部分提供 CRUD 服务(与 Realm 数据存储相关联)。在开发应用程序时,我希望 Realm 填充随机生成的实体,并认为使用现有的 PatientService 方法(返回 Observable>)比为此目的编写命令式方法更容易。当然…… ...我可以使用 Realm.isEmpty 但我将为其添加其他实体,因此想专门检查患者实体。对生成随机数据的单独 clss/struct 的调用已被放置在 PatientService 中,只是因为它似乎是一个合适的位置,但它可能在这里引起了混乱!也许 AppDelegate (或类似的***类)可能会更好。这有帮助吗?

以上是关于RxSwift 和控制流 - 一个坏主意?的主要内容,如果未能解决你的问题,请参考以下文章

RxSwift:重复(完成)流

RxSwift:链接流的问题

RxSwift observable 创建,它采用流本身的最后一个值

python控制流

CSAPP读书笔记--第八章 异常控制流

为啥程序流控制随机执行