93

Say you have a cache, and a method that will do something like the following:

if (wanted Foo is not in cache)
    cache.Add(new Foo())
Return Foo from cache

What would you call that method? GetFoo(), GetOrCreateFoo() or something else (and better)? Or should this really be divided into two methods?

Tor Livar
  • 1,193
  • 1
  • 9
  • 9

21 Answers21

59

In most cases a simple GetFoo suffices as the caller doesn't need to know that you are creating and caching it. That's what encapsulation is all about.

However, in some circumstances, creating is an expensive operation, so it's useful to know that you may be creating something on demand and in some cases it will be slow. In this case, a different naming convention makes it clearer to the caller. GetOrCreate() or Get(Options.CreateIfMissing) is a good hint to the caller.

(The behaviour should of course be noted in the documentation, but it's good to use a method name that reminds people about side effects while they are reading the code, without them having to bring up and read the documentation for every method that is called)

The sort of case I find this happening in most often is (for example) when finding a tree node (e.g. in an XML document) you might have CreateNode (to create a node without adding it to the tree) and AddNode (to add an existing node to the tree). In this case, an "Add a node if it doesn't already exist" needs to have a different, descriptive name, so I will use something like EnsureNodeExists to differentiate it and make the purpose clear.

Audwin Oyong
  • 2,247
  • 3
  • 15
  • 32
Jason Williams
  • 56,972
  • 11
  • 108
  • 137
  • You'd typically supply a `get` with some sort of unique key. In this case you're probably not looking for a specific key but for specific values of columns, so a `getFooByWhatever` might be suitable (obviously not actually using `whatever`). – Martijn Sep 12 '17 at 09:24
  • 2
    I like the `CreateIfMissing` wording. Nice! – lindon fox Mar 13 '18 at 08:42
18

How about Getsert? From get or insert, since update or insert is Upsert

Though I haven't seen any popular frameworks use this term, but this conforms to the idea that @Jason Williams pointed out, that:

  • It should be clear to the user that it would not just do a normal get
  • You don't have to go to the documentation to see what it does
  • Easy to pickup and intuitive? (I'm not sure)
Audwin Oyong
  • 2,247
  • 3
  • 15
  • 32
Louie Almeda
  • 5,366
  • 30
  • 38
  • 2
    I think GetFoo() is not clear because it doesn't let the caller know if they will get an empty result or not if the object doesn't already exist. So Getsert would be more clear. – John K Oct 07 '16 at 15:19
  • 2
    I like the portmanteau idea but `Getsert` makes me think of `get` + `assert`, which has a different meaning. – c z Jan 31 '19 at 12:31
  • I've coined this one on my own too before and been actively using it, `upsert` and `getsert` are practically flawless. – j4hangir Feb 23 '23 at 15:38
18

The words obtain and acquire seem to be well fitted. Especially obtain:

to come into possession of; get, acquire, or procure, as through an effort or by a request: to obtain permission; to obtain a better income.

One could say that in your case the caller of the method obtains the foo.

Isinlor
  • 1,111
  • 1
  • 13
  • 22
18

I know I'm very late at the question, but can I propose GrabFoo() as a convention for get-or-create-if-missing to differentiate it from GetFoo()?

Looking at the synonyms of Get, I see several suitable verbs, some already commonly used as method verbs. For example, Fetch already connotes fetching something from an external system. (e.g. database or network)

Grab seems like rarely used, and might be carrying an (albeit weak) semantic of I want you to get-or-create it, no matter what.

Ibrahim Arief
  • 8,742
  • 6
  • 34
  • 54
8

My preference is GetFoo() because the action from the point of view of the caller is getting and the cache is more of an implementation detail.

Audwin Oyong
  • 2,247
  • 3
  • 15
  • 32
Ofir
  • 8,194
  • 2
  • 29
  • 44
6

I propose using obtain. We've set this convention in our team and we feel pretty comfortable about that.

As from the Cambridge definition:

obtain: to get something, especially by asking for it, buying it, working for it, or producing it from something else.

And that's exactly what we need.

Victor Timoftii
  • 2,717
  • 1
  • 16
  • 15
4

I'd call it GetFoo, on the grounds that the caller doesn't care whether it's going to be given a new or an already-created Foo - it just wants to Get a Foo.

AakashM
  • 62,551
  • 17
  • 151
  • 186
2

For a cache, I would simply call it GetFoo(). A cache is designed to act as a facade behind a data source so that callers can easily access items without worrying about how they are or are not being loaded.

I'd call it GetFoo, but the document that if the requested object is not in the cache, that the cache will load it (and all the potential performance implications that might have).

Audwin Oyong
  • 2,247
  • 3
  • 15
  • 32
Alex Humphrey
  • 6,099
  • 4
  • 26
  • 41
2

Another option that makes sense if you are referential transparent or the object is a singleton.

Sometimes a getOrCreate() call is really lazy initialization. Thus you want to create one object and if it was already created return a reference to it. In this case I would call the method lazyGet which also is used in other libraries like javaslang's lazy.

MyObject lazyGet() {
}

This has one benefit on the call site. If your call is expensive in creation context your callee knows then that eager initialization can be used to move the call cost to a non critical section of your program.

P.S.: This also is used for memoization, which is an optimization technique where you return cached Objects of immutable data-structures.

Alexander Oh
  • 24,223
  • 14
  • 73
  • 76
2

I use Take instead of Get. Reasons why:

  • take also sounds a bit like make
  • to take has the same meaning as get in the given context
  • take sounds more forceful than get, so if I can't get it, I'll just take it
mchlstckl
  • 3,390
  • 2
  • 21
  • 21
2

Beget

A couple of definitions that seem to fit:

  • To cause to exist or occur; produce
  • To cause or create

The word also breaks down into the two ideas in your question.

"What's a good name for a method that gets or creates an object?"

Be = creates

Get = gets

Plus its really short.


Another alternative is Resolve.

I borrow that word from Autofac, which uses Resolve methods to get you an instance of an object, or creating it if necessary.

Casey Plummer
  • 2,629
  • 23
  • 20
1

I'd go for only GetFoo() just like most of the people have mentioned here.

Reason is - The method is responsible for returning the object instance. That is its primary responsibilty. If the object is not created, then create the object put it in cache and then return it. external callers, need not bother what method internally does to return the object, callers will simply call GetFoo() whenever needed. Method GetFoo() encapsulates and hides the complexity behind creating and caching the object. hence GetFoo()

this. __curious_geek
  • 42,787
  • 22
  • 113
  • 137
1

I know that topic has 6 years. But... I think that the best name is

getInstanceFoo()

or

getFooInstance()

as in singleton class.

Lasek
  • 11
  • 1
1

1. Find Synonyms (not good)

You can try to find a synonym for "get". However, you may thing that a getter that does not use "get" might mean something else, but you don't know exactly what it does. I would avoid using that approach as in the end it is never clean to understand what it does.

2. Use Adverbs as Suffix (not good)

You can add adverbs that specifies the get-Method by assuring that you do something. Like "getCreated", "getSafe", "getAssured", "getEnsured", "getInit", "getInitialized". That way it's clean to understand its a getter but also tells you, that something else it going to happen. However, you might not know if the name is part of the attribute or the get. Like "getSecureUrl". So I would avoid using a suffix for get.

3. Use Adverbs as Prefix (not good)

You can add averbs also as prefix, to tell what you are doing. Like "secureGet", "safeGet", "initGet", ... While this does not interfer with the property, you do not know whether it is a getter anymore or something else that does something upfront the getter without actually getting something. So a return value might be unexpected. I would avoid that approach as well.

4. Use words that describe what you actually do (maybe)

Instead of saying, this is a get-Method you can also say I have a method that initialized the value. That it also returns a value is a benefit to it. Something like:

function initNameid($name) { ... }

This way you know that you may initialize something as well and not only get something. That way you keep your getter clean and simple, without mixing it. However, as if you are searching something more standard you have to think about, that people might not find it if they are searching for getters. So it might not to be the best as well.

5. Enhancing the getter with additional properties (good)

You can add additional properties that tells the user that the getter does something more:

function getName($id, $create = false) { ... }

That way you provide the get function the information that it should try to force it's value if the boolean is true. If you use a proper IDE it also shows you the key of that arguement is "force", "create" or something similar, so you will always know what it does. Expectation-wise it might by the cleanest approach of all if you want to combine both.

6. Combine initialization and getter with...out combing them (good)

Ask yourself, why do you have to combine it anyways? Sure, it's a single line but... do you need that? How about simple doing it one after another:

initNameId($name);
getNameId($name);

Sometimes it is better to not mix something just because to have a single line or single function.

7. Do you actually create something or simple store it? (good)

If you just store something and something like that:

public static $name;
public static getName() {
if (!self::$name) $name = ...
  return self::$name;
}

If a getter just caches something as well, it is not necessary to change it's name. It's comming and no problem at all. So you do not need to solve a problem that does not exist.

8. Why do you need to combine two different meanings in one verb anyway? (maybe)

If you get or create something with one function... is it actually bad to name it that way? Like "getcreateProperty" or "getorcreateProperty", etc. is not so bad as it sounds. It is clear what it does. Sure, it is not a single verb, but you do A or B and then A. So why do you try to find C if you can stay at AB and everyone know what it means? Not bad to ask if there is something, but as those are two different things, there is not need to be creative and think of new words. It's important however that you do not write the additional meaning in Camelcase otherwise you might confuse it with a potential name of a property like "getCreateDate" might either get you an creation date or gets the date securely. "getcreateDate" or maybe "get_createDate" however implies there is more to it. However, it might still be a little confusing.

Christian
  • 11
  • 2
1

You can use ForceGet(), GetOrNew(), GetOrCreate(). Whatever you select be consistent throughout

Otabek Kholikov
  • 1,188
  • 11
  • 19
0

It depends what kind of object that make sense to user.

If the creation is not important to user, it is GetFoo; otherwise, call it createOrGetFoo.

If the differentiation of concepts is needed, you might have methods like GetFoo, CreateFoo and createOrGetFoo.

I prefer to name it as GetFoo according to your given information.

OmniBus
  • 854
  • 1
  • 6
  • 25
0

Assuming this method is on a cacheManager then fetch(wanted) [or get(wanted) depending on your personal pref] is enough - with the API doc indicating that the item is created if it doesn't exist.

Wanted should be typed accordingly - so there's no need for Foo in the method name.

dasher
  • 133
  • 1
  • 5
0

Like upsert (update and insert), getsert as in get or insert and return.

Or get creative:

  • greate as in get or create

  • gadd as in get or add

psyanite
  • 89
  • 2
  • 10
  • 3
    Good naming helps understand the code – but "upsert", "greate", "gadd" are not easily understandable. – Beat Jan 08 '21 at 13:05
0

I would call it "GetOrDefault()". In case of no match: returns a constructed instance as established in the same method but without saving the instance physically. Later the instance properties can be further edited, so I would call Upsert() to save.

jangix
  • 49
  • 7
-1

If this design makes logical sense in your application, then I think GetOrCreateFoo is an appropriate name.

Another approach that clearly conveys its purpose would be

GetFoo(bool createIfNotExists)

Of course, if we're really talking cache the implementing side might not care whether or not the item was just created. The above applies in cases where the caller actually does need to know about the possible creation of Foo and its implications (such as when retrieving from filesystem or db, perhaps?)

David Hedlund
  • 128,221
  • 31
  • 203
  • 222
  • `GetOrCreateFoo` : I don't agree here. Method just gets the object of foo, if it is not created, it will create the object, put it in cache and return the object. creation and caching is too internal fore the method hence need not be `GetOrCreateFoo`. – this. __curious_geek Jul 06 '10 at 07:16
  • @this. __curious_geek: I can agree with that in the specific case of cache, but the question is "what's a good name for a method that gets or creates an object" and in the more general case, there might very well be scenarios where the caller does want control of this (consider the immensely useful `FileMode.OpenOrCreate` in `System.IO.File.Open`) – David Hedlund Jul 06 '10 at 07:47
  • 1
    Adding a boolean argument to a getter to add this functionality doesn't imporve readability unless you are using a programming language with named parameters. – TFennis Dec 10 '13 at 13:52
-2

I would call it "getFoo()" too and add to your comments what the function does if a Foo is not existent.

InsertNickHere
  • 3,616
  • 3
  • 26
  • 23
  • 1
    -1 The name should convey what the method does, you shouldn't need a comment. Also, I wouldn't expect a 'get' function to have side effects such as creating something. – onedaywhen Oct 08 '14 at 13:39