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()
开发者_如何学Cor something else (and better)? Or should this really be divided into two methods?
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.
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.
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)
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.
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.
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
.
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.
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.
I use Take
instead of Get
. Reasons why:
take
also sounds a bit likemake
- to
take
has the same meaning asget
in the given context take
sounds more forceful thanget
, so if I can'tget
it, I'll justtake
it
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).
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()
I know that topic has 6 years. But... I think that the best name is
getInstanceFoo()
or
getFooInstance()
as in singleton class.
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.
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.
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.
Like upsert
(update and insert), getsert
as in get or insert and return.
Or get creative:
greate
as in get or creategadd
as in get or add
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.
6. Combine initialization and getter without 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:
initName($name);
getNameId($name);
Sometimes it is better to not mix something just because to have a single line.
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 yu 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? (good)
If you get or create something with one function... is it actually bad to name it that way? "getCreate" or "getOrCreate", 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.
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.
You can use ForceGet(), GetOrNew(), GetOrCreate(). Whatever you select be consistent throughout
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?)
I would call it "getFoo()" too and add to your comments what the function does if a Foo is not existent.
精彩评论