Functional equivalent of decorator pattern?

后端 未结 10 2110
悲&欢浪女
悲&欢浪女 2021-02-02 06:34

What is the functional programming equivalent of the decorator design pattern?

For example, how would you write this particular example in a functional style?

10条回答
  •  别那么骄傲
    2021-02-02 07:36

    type Window = {Description: string}
    type HorizontalScroll = {HPosition: int}
    type VerticalScroll = {VPosition: int}
    type Feature = 
        | HorizontalScroll of HorizontalScroll
        | VerticalScroll of VerticalScroll
    
    let drawWithFeatures w (f: Feature) = 
        match f with
        | HorizontalScroll h ->  {Description= w.Description + "Horizontal"}
        | VerticalScroll v -> {Description= w.Description + "Vertical"} 
    
    type FeatureTwo = Red of int| Blue of int | Green of int | Feature of Feature
    let rec drawWithMoreFeatures (w: Window) (ft:FeatureTwo)=
            match ft with 
            | Red x     ->  {Description = w.Description + "Red"} 
            | Green x   ->  {Description = w.Description + "Green"} 
            | Blue x    ->  {Description = w.Description + "Blue"}
            | Feature f ->  drawWithFeatures w f
    
    let window = {Description = "Window title"}
    let horizontalBar =   HorizontalScroll {HPosition = 10}
    let verticalBar =  VerticalScroll {VPosition = 20}
    
    [Red 7; Green 3; Blue 2; Feature horizontalBar; Feature verticalBar] |> List.fold drawWithMoreFeatures window
    

    F# attempt

    This is my attempt at creating something sensible in F# since you asked for many examples. I'm a little rusty so hopefully nobody will shame me :P. The decorator basically requires two parts, new behaviors and new data. New behaviors are exceedingly easy in functional languages as they are "just another function", since functions are inherently decoupled from objects. New data is actually similarly easy and there's several ways you can achieve this, the simplest being a tuple. You can see I've created a new datatype that is a superset of the previous, and I've called the existing function for that existing behavior. So we have our old data and old behavior still respected, but we also have new behavior and new data.

提交回复
热议问题