Model view controller 如何分别观察接口的不同概念?

Model view controller 如何分别观察接口的不同概念?,model-view-controller,generics,interface,f#,Model View Controller,Generics,Interface,F#,基本上,我试图做的是有一个通用的模拟器界面,它作为模型和用户界面之间的失去耦合,作为视图。我的模拟器界面如下所示: type ISimulator<'Collection, 'Item, 'Value> = inherit System.IObservable<'Collection> inherit System.IObservable<ISimulator<'Collection, 'Item, 'Value>> abstract

基本上,我试图做的是有一个通用的模拟器界面,它作为模型和用户界面之间的失去耦合,作为视图。我的模拟器界面如下所示:

type ISimulator<'Collection, 'Item, 'Value> =
  inherit System.IObservable<'Collection>
  inherit System.IObservable<ISimulator<'Collection, 'Item, 'Value>>
  abstract Start:           unit -> unit
  abstract Stop:            unit -> unit
  abstract Reset:           unit -> unit
  abstract Reset:           'Collection -> unit
  abstract Advance:         int<gen> -> unit
  abstract InitialState:    'Collection
    with get
  abstract CurrentState:    'Collection
    with get
  abstract Rule:            ('Item -> 'Value)
    with get, set
  abstract Generation:      int<gen>
    with get, set
  abstract Speed:           float<gen/sec>
    with get, set
  abstract Running:         bool
    with get
类型模拟程序
继承System.IObservable单元
摘要预付款:整数->单位
抽象InitialState:'集合
带着
抽象CurrentState:'集合
带着
抽象规则:('Item->'值)
用get,set
抽象生成:int
用get,set
抽象速度:浮点
用get,set
摘要:布尔
带着
“Collections是数据收集的类型,”“Item”是单个数据项的类型,“Value”是其实际值的类型(例如,等等)。现在,排队

inherit System.IObservable<ISimulator<'Collection, 'Item, 'Value>>
inherit System.IObservable'。此版本的F#中不允许这样做。
实际上,我想让这个接口说,作为模拟运行的数据的集合和模拟器本身都是可以单独观察的。最后,我希望我的用户界面的一部分显示当前数据(例如矩阵),另一部分显示和控制模拟器,带有一些按钮,如“运行”、“停止”、“重置”等,因为模拟器也可能通过其他方式停止,而不仅仅是单击按钮(例如,在达到某个特定状态、生成等)后,该控制也需要来自模拟器的更新,但不是数据状态,而是模拟器本身

我编写的集合接口不可能是可观察的,因为在模拟过程中不会修改该集合,而是通过应用函数进行转换,转换将生成一个新集合,然后模拟器将其存储(并通知观察者该集合)

我该怎么办

  • 打破不变性的概念 始终保持相同的收藏(在 身份条款,未包含 值),它只是随时间而变化 而不是生产新的,改良的 收藏
  • 断开-断开耦合,让我的用户 我知道确切的情况 将在外部 对于接口,请提供第二个 观察模拟器的方法 本身?具有所有用户界面 需要从中更新的组件 模拟器观察整个过程 事情,不仅仅是相关数据
  • 创建一个单独的接口来 观察收集,并让我的 模拟器实现工具 两个接口
  • 还有别的吗

您是否考虑过像传统事件一样,通过属性公开可观察的对象

type ISimulator<'Collection, 'Item, 'Value> =
  abstract Items:           System.IObservable<'Collection>
  abstract Control:         System.IObservable<ISimulator<'Collection, 'Item, 'Value>>
  abstract Start:           unit -> unit
  ...
类型模拟程序

抽象控制:System.IObservable接下来,我对IObservable进行了一个简单的实现,然后根据提供的接口定义dahlbyk公开了其中的公共属性。我找到了这个实现的基本思想,并从中概括了一点:

  open System

  type Observable<'a>() =
    let mutable _observers: List<IObserver<'a>> = []
    let Notify func =
      _observers
      |> Seq.map(fun (observer: IObserver<'a>) -> async { return func observer} )
      |> Async.Parallel
      |> Async.RunSynchronously
      |> ignore

    interface IObservable<'a> with

      member this.Subscribe (observer: IObserver<'a>) =
        _observers <- observer :: _observers
        { new IDisposable with
              member this.Dispose() =
                _observers <- _observers |> List.filter((<>) observer) }

    member this.Next value =
      Notify(fun (observer: IObserver<'a>) -> observer.OnNext value)

    member this.Error error =
      Notify(fun (observer: IObserver<'a>) -> observer.OnError error)

    member this.Completed() =
      Notify(fun (observer: IObserver<'a>) -> observer.OnCompleted)
开放系统
类型可观察>=[]
让我们通知func=
_观察员
|>序列图(乐趣)(观察者:带
成员this.Subscribe(observer:IObserver)->observer.OnNext值)
请记住此错误=
通知(乐趣(观察者:IObserver)->observer.OnCompleted)
包含此实现的实例作为属性的类只是将其视为一个
可观察的
接口。我认为这在松耦合方面很好,并且仍然允许在观察者/可观察对的任一端非常直接地使用


S.:S:这也是为什么我喜欢F-的原因,这整个构造将是一个完全混乱的语言,比如C++,但是在这里我可以把函数传递给另一个函数,以便把它应用到所有的观察者身上。

为什么代码会以如此奇怪、不可预测的方式着色?除了上面提到的错误之外,这段代码是有效的F#,如果我删除了有问题的行,它会编译得非常完美。堆栈溢出不会语法突出显示F#源代码是否正确。特别是,它会被“in
”a
弄糊涂。好的,我终于决定这样做了e、 也就是说,组合,并提供IOObservable的基本通用实现,我公开了如您所述的proterties。我仍然不确定这是否是最好的解决方案,但比我目前所能想到的任何其他解决方案都要好。;)如果您确实提出了更好的方案,请告诉我们。:)好了,现在我已经有了一个IObservable的现成实现,这实际上还不算太糟糕。基本上,我已经实现了interface plus方法来激活所有注册观察者上的“OnNext”、“OnError”和“OnCompleted”事件,并且只有此类的实例。作为公共财产。我将在下面的回答中发布实现。
  open System

  type Observable<'a>() =
    let mutable _observers: List<IObserver<'a>> = []
    let Notify func =
      _observers
      |> Seq.map(fun (observer: IObserver<'a>) -> async { return func observer} )
      |> Async.Parallel
      |> Async.RunSynchronously
      |> ignore

    interface IObservable<'a> with

      member this.Subscribe (observer: IObserver<'a>) =
        _observers <- observer :: _observers
        { new IDisposable with
              member this.Dispose() =
                _observers <- _observers |> List.filter((<>) observer) }

    member this.Next value =
      Notify(fun (observer: IObserver<'a>) -> observer.OnNext value)

    member this.Error error =
      Notify(fun (observer: IObserver<'a>) -> observer.OnError error)

    member this.Completed() =
      Notify(fun (observer: IObserver<'a>) -> observer.OnCompleted)