2016-01-01 5 views
1

У меня есть три функции в модуле SetBehaviour, который вызывает GetBehviour, который читает текстовый файл и десериализует его обратно к моим типам и возвращает его обратно в useCases. Затем я получаю доступ к объекту, который я хочу, «let behavior = useCases.Item (useCaseIdentifier)»F # заданное значение функции

Мой вопрос: есть ли способ установить «GlobalBehavior» на возвращаемое значение «SetBehaviour», поэтому я могу назвать «GlobalBehaviour» 'непосредственно, не просматривая чтение текстового файла и десериализацию каждый раз?

let GlobalBehaviour = //The return value of SetBehaviour here 


let GetBehaviour = 
    let useCases = Data.ReadUseCases 
    let deserializedUseCases = JsonConvert.DeserializeObject<Map<string,Types.UseCase>>(useCases) 
    deserializedUseCases 


let SetBehaviour useCaseIdentifier = 
    let useCases = GetBehaviour 
    let behavior = useCases.Item(useCaseIdentifier) 
    behavior 
+0

Вы пытаетесь кэшировать результат после того, как функция вызывается? Или вы просто хотите инициализировать значение некоторым «по умолчанию» при загрузке приложения? –

+0

Вы хотите, чтобы SetBehavior помнил, что было прочитано из текстового файла? С другой стороны, почему «SetBehavior» не назвал нечто более подходящим, как «GetUsecaseById»? – Christian

+0

Да, я пытаюсь кэшировать результат SetBehaviour в GlobalBehaviour. Поэтому я могу вызвать Module.GlobalBehaviour из другого модуля. –

ответ

4

Ответ зависит от контекста. Например, это какая-то инициализация, которая происходит только один раз, или это часто меняется?

В общем, лучше избегать глобального изменчивого состояния в F # и вместо этого помнить последнее поведение где-то в модуле, который обращается к модулю, который вы показываете в своем вопросе. Таким образом, клиент контролирует состояние (и есть различные способы сделать это лучше). Кроме того, если вы пишете параллельную систему, имеет смысл использовать агент вместо этого.

Однако основное решение с использованием мутации будет выглядеть примерно так:

let mutable GlobalBehaviour = None // Initially the global behaviour is not set 

let SetBehaviour useCaseIdentifier = 
    let useCases = GetBehaviour 
    let behavior = useCases.Item(useCaseIdentifier) 
    GlobalBehaviour <- Some behaviour // Now we set it to the last one 
    behaviour 

На практике это может сделать больше смысла использовать какой-то другой подход. Например, если вы хотите запустить это только один раз, вы можете использовать значение lazy (которое оценивает функцию один раз и кэширует результат, чтобы ваша конфигурация не читалась повторно). Но трудно дать лучший ответ без каких-либо подробностей.

2

Вы можете кэшировать случаи использования считанных из файла при инициализации модуля следующим образом:

module UseCaseModule 
let GlobalBehaviour = //Retreive use case from cachedUseCases and useCaseId 
let private cachedUseCases = JsonConvert.DeserializeObject<Map<string,Types.UseCase>>(Data.ReadUseCases) 
let mutable private useCaseId = None 
let private SetBehaviour useCaseIdentifier = 
    useCaseId <- useCaseIdentifier 
Смежные вопросы