Денис Крешихин

Денис
Крешихин

iOS-разработчик с 15+ летним опытом

Тимлид/сеньор по обстоятельствам

Интересы: swift, uikit, rxswift, oop/ood, devops, agile

2024 © Денис Крешихин

Абстрактная фабрика на 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". Что соответсвует ООП-механизму перекрытию виртуальных функций в наследнике.