【问题标题】:refactoring 2 closely coupled methods重构 2 个紧密耦合的方法
【发布时间】:2011-08-26 05:04:13
【问题描述】:

好的,我正在制作分布式系统的模型。 mClass(对象)的每个实例由 1 个线程使用。可变数据不能在 mClass 对象之间传递 这是一个类似于我所拥有的代码示例:

type mClass (mID:id)=
    member this.ID=mID

    let resolve : id->mClass  =... //This function turns IDs into the objects they represnt
    ...
    let managementInfo = ref Some mutableData

    //this should only ever be called by the GiveControl method.
    private member this.TakeControl (frozenData) =
        let defrostedData = ... //a variable that works out the unfrozen version of the frozenData
        managementInfo := Some defrostedData


    ///This is a helper that ensure that when ever someone else is told to take control 
    ///that all my internal data and any functions i need to call to tell others are done
    ///And convert the data a nonmutable form 
    ///(Mutable data can not be tranfered between different instances of of mClass (objects), 
    ///as this is a mockup of a distributed system, where the instances of mClass can't
    ///@param: nID this ID of the object we are giving control to
    ///@param: callbacks: a list of functions to call to tell other objects i've given control 
    private member this.GiveControl nID (callbacks: list<id->unit>) =
        let updateInternalData = ... //A function to upate my internal state
        updateInternalData;
        ignore (List.map (fun f-> f nID) callbacks);
        let freezeData data= ... //a function make our mutableData into nonmutable data
        let frozenData = (!managemenInfo).Value|>freezeData 
        managemenInfo:=None;
        (nID|>resolve).TakeControl (frozenData)

    ...

私有成员 this.GiveControl 最初被声明为: 让给予控制 但它让编译器抱怨错误声明了一个新类型,直到我将它改为私有方法。

问题是,我怎样才能重新分解这段代码, 将两种方法合二为一。 (或至少使 GiveControl 只能从该对象内调用(实际上是私有的),而 TakeControl 只能从 GiveControl 调用)

【问题讨论】:

    标签: f# refactoring


    【解决方案1】:

    正如您所说,您最初将 giveControl 作为一个 let,这正是您需要做的。 带有 let 的事物是真正的私有值。无法从您的对象外部访问它们。

    F# 中的类要求在成员之前声明。 F# 也不是类方法的单一逾越节, 因此您的 let 可以引用您需要的任何方法。

    类型 mClass (mID:id)= 成员 this.ID=mID

    let resolve : id->mClass  =... //This function turns IDs into the objects they represnt
    ...
    let managementInfo = ref Some mutableData
    let giveControl nID (callbacks: list<id->unit>) =
    ...
    
    private member this.TakeControl (frozenData) =
        ...
    

    但是,这并不能解决您的第二个问题

    【讨论】:

      【解决方案2】:

      为什么你需要保护自己免受自己的伤害?甚至这个版本也涉及到另一个 mClass 的变异状态(您是从给定线程而不是获取线程调用 TakeControl)。也许与其担心传递可变信息,不如使用消息传递系统并对信息的使用保持清醒(即传递后的空引用)。

      如果你真的想要内部访问某个东西而不是 let 绑定是要走的路。您可以将这些控制方法移动到一个单独的类中,并使用一个 let 来为每个 mClass(或一个参数)创建每个实例。但是,没有办法保证 TakeControl 的最后一部分可以从 GiveControl 调用,除非您以某种方式将 Giving 和 Take 的责任转移到接收端。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-07-29
        • 2011-05-24
        • 2017-05-09
        • 1970-01-01
        • 2012-11-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多