Sunday, November 27, 2011

Sample in detail - Chain of Responsibility pattern

this post is to use the Chain of Responsibility pattern to implement a simple function to show the byte in KB, MB, or GB.

In this post, I use the Chain of Responsibility pattern to replace the while loop. The loop itself is done by the composite function defined below. There is another version to composite functions but I found it not easy to debug.

The process will stop when the canContinueF returns false. The result value won't be processed and just slip through other function. The F# provides a good generalization so I do not have to refactor any design pattern code.

let chainTemplate processFunction canContinue s =
    if canContinue s then
        processFunction s
    else s
let composite f a n =
    [1..n] |> (fun _ -> f) |> Seq.fold (fun acc n -> acc |> n) a
let getReadableSize value =
    let unitNames = ["B"; "KB"; "MB"; "GB"; "TB"]
    let unit = 1000.
    let canContinueF (v,unitNameIndex) = v >= unit && unitNameIndex < unitNames.Length-1
    let processF (x, unitNameIndex) = (x / unit, unitNameIndex+1)
    let chainFunction = chainTemplate processF canContinueF   //combine two functions to get a chainFunction
    let (v,i) = composite chainFunction value unitNames.Length //value |> chainFunction |> chainFunction
    (v, unitNames.[i]) 
let (v,name) = getReadableSize (1001000000000000., 0)
printfn "%f %s" (System.Math.Round(v, 2)) name

No comments: