Created
November 30, 2016 01:28
-
-
Save bleis-tift/c8419630f982aa5ff71c8f0af659778a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//================================================================================ | |
// 共通 | |
//================================================================================ | |
type EmailAddress = | |
{ EAValue: string } | |
type SurfaceAddress = | |
{ SAValue: string } | |
type Customer = | |
{ EmailAddress: EmailAddress | |
SurfaceAddress: SurfaceAddress } | |
type ShoppingCart<'TItem> = | |
{ Items: 'TItem list } | |
//================================================================================ | |
// F# way (DU + match(function) expr) | |
//================================================================================ | |
type Item = | |
| FDownloadableItem | |
| FSurfaceItem | |
module FunctionalShipping = | |
let ship customer = function | |
| FDownloadableItem -> printfn "%sにダウンロードURL付きメールを送信" customer.EmailAddress.EAValue | |
| FSurfaceItem -> printfn "%sに配送" customer.SurfaceAddress.SAValue | |
module FunctionalShoppingCart = | |
let empty : ShoppingCart<Item> = { Items = [] } | |
let add (item: Item) cart = { cart with Items = item::cart.Items } | |
let shipAll customer cart = | |
cart.Items | |
|> List.iter (FunctionalShipping.ship customer) | |
//================================================================================ | |
// Objective way(double dispatch(polymorphism)) | |
//================================================================================ | |
type IItem = | |
abstract Ship: shipper:ObjectiveShipping * customer:Customer -> unit | |
and ObjectiveShipping () = | |
member __.Ship(item: IItem, emailAddress: EmailAddress) = | |
printfn "%sにダウンロードURL付きメールを送信" emailAddress.EAValue | |
member __.Ship(item: IItem, surfaceAddress: SurfaceAddress) = | |
printfn "%sに配送" surfaceAddress.SAValue | |
type ODownloadableItem () = | |
interface IItem with | |
member this.Ship(shipper, customer) = | |
shipper.Ship(this, customer.EmailAddress) | |
type OSurfaceItem () = | |
interface IItem with | |
member this.Ship(shipper, customer) = | |
shipper.Ship(this, customer.SurfaceAddress) | |
module ObjectiveShoppingCart = | |
let empty : ShoppingCart<IItem> = { Items = [] } | |
let add (item: IItem) cart = { cart with Items = item::cart.Items } | |
let shipAll customer (cart: ShoppingCart<IItem>) = | |
let shipper = ObjectiveShipping () | |
cart.Items | |
|> List.iter (fun item -> item.Ship(shipper, customer)) | |
//================================================================================ | |
// usage | |
//================================================================================ | |
let customer = | |
{ EmailAddress = { EAValue = "[email protected]" } | |
SurfaceAddress = { SAValue = "どこか" } } | |
// F# way | |
let fcart = | |
FunctionalShoppingCart.empty | |
|> FunctionalShoppingCart.add FDownloadableItem | |
|> FunctionalShoppingCart.add FSurfaceItem | |
fcart |> FunctionalShoppingCart.shipAll customer | |
// Objective way | |
let ocart = | |
ObjectiveShoppingCart.empty | |
|> ObjectiveShoppingCart.add (ODownloadableItem()) | |
|> ObjectiveShoppingCart.add (OSurfaceItem()) | |
ocart |> ObjectiveShoppingCart.shipAll customer |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment