重构2个紧密耦合的方法

时间:2011-05-16 06:26:13

标签: f# refactoring

好的,我正在制作一个分布式系统的模型。 mClass(object)的每个实例由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 但是它让编译器抱怨错误地声明了一个新类型,直到我把它改成私有方法。

问题是,如何重新考虑此代码, 将两种方法合并为一种。 (或至少使GiveControl只能从这个对象中调用(真正的私有),而TakeControl只能从GiveControl调用)

2 个答案:

答案 0 :(得分:0)

为什么你需要保护自己?即使这个版本也涉及到另一个mClass的状态变化(你从给定的线程调用TakeControl而不是调用线程)。也许不要担心传递可变信息,你应该使用消息传递系统,并对信息使用保持理智(即传递后的空引用)。

如果你真的想要内部访问某些东西,那么让绑定成为可能。您可以将这些控制方法移动到单独的类中,然后让每个mClass(或参数)创建每个实例。然而,除非你以某种方式将Giving和Taking的责任转嫁给接收端,否则无法保证TakeControl的最后一部分可以从GiveControl调用。

答案 1 :(得分:0)

正如你所说的那样,你或者将控制权作为一种让步,这正是你需要做的事情。 与let-delare相关的东西是真正的私人价值观。无法从对象外部访问它们。

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) =
    ...

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

相关问题