"GetOrCreate" - у этой идиомы есть установленное имя? - PullRequest
18 голосов
/ 23 сентября 2009

Хорошо, рассмотрим эту распространенную идиому, которую многие из нас использовали много раз (я полагаю):

class FooBarDictionary
{
    private Dictionary<String, FooBar> fooBars;

    ...

    FooBar GetOrCreate(String key)
    {
        FooBar fooBar;

        if (!fooBars.TryGetValue(key, out fooBar))
        {
            fooBar = new FooBar();
            fooBars.Add(key, fooBar);
        }

        return fooBar;
    }
}

Есть ли у него какое-либо установленное имя?

(Да, он написан на C #, но его можно «легко» перенести в C ++. Отсюда и этот тег.)

Ответы [ 5 ]

9 голосов
/ 23 сентября 2009

Я всегда называю такие функции obtainSomething().

9 голосов
/ 23 сентября 2009

Это в некоторой степени зависит от того, почему вы делаете это - идиома, которую я видел, называется «запоминание, кэширование, инициализация по требованию, создание при первом использовании». Обычно я вызываю метод «sureFoo», а не «GetOrCreate»

5 голосов
/ 23 сентября 2009

Ленивая загрузка

http://en.wikipedia.org/wiki/Lazy_loading

1 голос
/ 23 сентября 2009

Я не уверен в общем названии программирования для шаблона высокого уровня, но в Perl есть замечательное поведение под названием Autovivification , а именно - автоматическое создание ключа хеша (карты) с неопределенным значением при запросе значение несуществующего ключа в хэше.

0 голосов
/ 25 мая 2012

In C # ...

... У меня есть DefaultingDictionary <>, который делает по этому поводу. В качестве бонуса

  • Вы можете указать значение по умолчанию или Заводская функция , чтобы создать значения для отсутствующих ключей:
  • поставляется с неявным преобразованием из IDictionary <> (перенос словаря)
  • поставляется с методами расширения для преобразования любого словаря в DefaultingDictionary <> на лету

Полный код:

Расширения .AsDefaulting могут использоваться для прозрачного использования любого IDictionary<> в качестве значения по умолчанию, поэтому вы можете выбрать использование любого словаря (даже, например, полученного из стороннего API) в качестве значения по умолчанию, и базовый контейнер будет быть обновленным с любыми 'автоматически оживляемыми' предметами.

Используйте это как

IDictionary<string, MyItem> dict = LoadFromDatabase();

// using a fixed value
SomeFunc(dict.AsDefaulting(defaultItem));

// using an independent generator function
var defaulting = dict.AsDefaulting(() => new MyItem { Id = System.Guid.NewGuid() });

// using a keydepedent generator function
var defaulting = dict.AsDefaulting(key => LazyLoadFromDatabase(key));

Некоторые тестовые случаи

включены:

...