mirror of
https://github.com/thma/LtuPatternFactory.git
synced 2024-11-30 02:03:47 +03:00
start with abstract factory example
This commit is contained in:
parent
0fdb74c8e5
commit
cbee34e4e6
@ -15,7 +15,8 @@ extra-source-files: README.md
|
|||||||
|
|
||||||
executable LtuPatternFactory
|
executable LtuPatternFactory
|
||||||
hs-source-dirs: src
|
hs-source-dirs: src
|
||||||
other-modules: Adapter
|
other-modules: AbstractFactory
|
||||||
|
, Adapter
|
||||||
, Builder
|
, Builder
|
||||||
, Composite
|
, Composite
|
||||||
, Iterator
|
, Iterator
|
||||||
@ -25,8 +26,15 @@ executable LtuPatternFactory
|
|||||||
, Strategy
|
, Strategy
|
||||||
, TemplateMethod
|
, TemplateMethod
|
||||||
, Visitor
|
, Visitor
|
||||||
|
, Coerce
|
||||||
|
, IdiomBrackets
|
||||||
main-is: Main.hs
|
main-is: Main.hs
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
build-depends: base >= 4.7 && < 5
|
build-depends: base >= 4.7 && < 5
|
||||||
, containers
|
, containers
|
||||||
, mtl
|
, mtl
|
||||||
|
, aeson
|
||||||
|
, aeson-pretty
|
||||||
|
, text
|
||||||
|
, directory
|
||||||
|
, bytestring
|
||||||
|
60
src/AbstractFactory.hs
Normal file
60
src/AbstractFactory.hs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
{-# LANGUAGE DeriveGeneric, DeriveAnyClass #-}
|
||||||
|
{-# LANGUAGE ScopedTypeVariables #-}
|
||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
module AbstractFactory where
|
||||||
|
import GHC.Generics (Generic) -- needed to derive type class instances declaratively
|
||||||
|
import Data.Aeson (ToJSON, FromJSON, eitherDecode, toJSON) -- needed to provide JSON encoding/decoding
|
||||||
|
import Data.Text
|
||||||
|
import Data.Aeson.Text (encodeToTextBuilder)
|
||||||
|
import Data.Text.Lazy (toStrict)
|
||||||
|
import Data.Text.Lazy.Builder (toLazyText)
|
||||||
|
import qualified Data.ByteString.Lazy as B (readFile)
|
||||||
|
import Data.Typeable (Typeable, TypeRep, typeRep) -- runtime type reflection
|
||||||
|
|
||||||
|
data User = User Integer String String String deriving (Show, Read, Eq, Generic, ToJSON, FromJSON)
|
||||||
|
|
||||||
|
data Post = Post Integer Integer String deriving (Show, Read, Eq, Generic, ToJSON, FromJSON)
|
||||||
|
|
||||||
|
-- | load persistent entity of type a and identified by id
|
||||||
|
retrieveEntity :: forall a. (FromJSON a, Read a, Typeable a) => Text -> IO a
|
||||||
|
retrieveEntity id = do
|
||||||
|
-- compute file path based on type and id
|
||||||
|
let jsonFileName = getPath (typeRep ([] :: [a])) id
|
||||||
|
parseFromJsonFile jsonFileName :: FromJSON a => IO a
|
||||||
|
|
||||||
|
-- | store persistent entity of type a and identified by id to the backend
|
||||||
|
storeEntity :: forall a. (ToJSON a, Show a, Typeable a) => Text -> a -> IO ()
|
||||||
|
storeEntity id entity = do
|
||||||
|
let jsonFileName = getPath (typeRep ([] :: [a])) id
|
||||||
|
writeFile jsonFileName (showJson entity)
|
||||||
|
where
|
||||||
|
-- create a JSON representation of an entity
|
||||||
|
showJson :: (ToJSON a) => a -> String
|
||||||
|
showJson = unpack . toStrict . toLazyText . encodeToTextBuilder . toJSON
|
||||||
|
|
||||||
|
-- | compute path of data file
|
||||||
|
getPath :: TypeRep -> Text -> String
|
||||||
|
getPath tr id = ".stack-work/" ++ show tr ++ "." ++ unpack id ++ ".json"
|
||||||
|
|
||||||
|
-- | read from file fileName and then parse the contents as a FromJSON instance.
|
||||||
|
parseFromJsonFile :: FromJSON a => FilePath -> IO a
|
||||||
|
parseFromJsonFile fileName = do
|
||||||
|
contentBytes <- B.readFile fileName
|
||||||
|
case eitherDecode contentBytes of
|
||||||
|
Left msg -> fail msg
|
||||||
|
Right x -> return x
|
||||||
|
|
||||||
|
abstractFactoryDemo = do
|
||||||
|
putStrLn "AbstractFactory -> type class polymorphism"
|
||||||
|
let user1 = User 4711 "Heinz" "Meier" "hm@meier.com"
|
||||||
|
let post1 = Post 1 4711 "This is my first post"
|
||||||
|
storeEntity "4711" user1
|
||||||
|
storeEntity "1" post1
|
||||||
|
user2 <- retrieveEntity "4711" --
|
||||||
|
if user1 == user2
|
||||||
|
then
|
||||||
|
putStrLn "user data successfully restored"
|
||||||
|
else putStrLn "user data restore failed"
|
||||||
|
print user2
|
||||||
|
post2 <- retrieveEntity "1" :: IO Post
|
||||||
|
print post2
|
@ -10,6 +10,7 @@ import TemplateMethod
|
|||||||
import NullObject
|
import NullObject
|
||||||
import Iterator
|
import Iterator
|
||||||
import Coerce
|
import Coerce
|
||||||
|
import AbstractFactory
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = do
|
main = do
|
||||||
@ -24,3 +25,4 @@ main = do
|
|||||||
templateMethodDemo
|
templateMethodDemo
|
||||||
nullObjectDemo
|
nullObjectDemo
|
||||||
iteratorDemo
|
iteratorDemo
|
||||||
|
abstractFactoryDemo
|
||||||
|
Loading…
Reference in New Issue
Block a user