Абстрактная фабрика на Haskell
К функциональным языкам программирования я уже давно испытываю неподдельный интерес, особенно к ML-семейству и в частности к Haskell. Пожалуй такой же трепет я испытываю только к LISP-языкам. Но к сожалению практических книг по созданию приложений на Haskell очень и очень мало, поэтому я решил разбираться самостоятельно. На данный момент сделал набросок реализации абстрактной фабрики на Haskell. Потом попробую реализовать и другие ООП-паттерны в таком же виде как я сделал это для Go при написании хабростатьи Язык Go: реабилитация императивного программирования.
Работает это следующим образом. Определяется тип AbstractProduct
и тип AbstractFactory
, аналогично как абстрактные классы в мире ООП. Тип AbstractFactory
имеет поля-функции вида createProduct***
. Затем конкретная реализация фабрики создаётся путем присваивания этим полям конкетных функций, которые заполняют поля типа AbstractProduct
.
Main.hs —
data AbstractProduct = AbstractProduct{
getNameOf :: String
}
data AbstractFactory = AbstractFactory{
createProductABy :: AbstractProduct,
createProductBBy :: AbstractProduct
}
factory1 = AbstractFactory{
createProductABy = AbstractProduct{
getNameOf = "ProductA1"
},
createProductBBy = AbstractProduct{
getNameOf = "ProductB1"
}
}
factory2 = AbstractFactory{
createProductABy = AbstractProduct{
getNameOf = "ProductA2"
},
createProductBBy = AbstractProduct{
getNameOf = "ProductB2"
}
}
factory3 = factory1{
createProductABy = AbstractProduct{
getNameOf = "ProductB2"
}
}
main = putStrLn ("show " ++ (show $ getNameOf $ createProductABy $ factory3))
Т.к. Haskell позволяет создавать копии переменной, перекрывая некоторые поля, то таким образом получается реализовать механизм близкий к наследованию. В листинге это продемонстрированно при создании factory3
на основе factory1
. Соответсвенно factory3
, в отличии от други фабрик, будует создавать продукты "ProductA1" и "ProductB2". Что соответсвует ООП-механизму перекрытию виртуальных функций в наследнике.