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)