2

Imagine you have such routines

/*just do X. Fail if any precondition is not met*/
doX()

/*take care of preconditions and then do X*/
takeCareOfPreconditionsCheckIfNeededAtAllAndThenDoX() 

A little bit more concrete example:

/*create directory. Most probably fail with error if any precondition is not met (folder already exists, parent does not exists)*/
createDirectory(path_name)

/*take care of preconditions (creates full path till folder if needed, checks if not exists yet) and then creates the directory*/
CheckIfNotExistsYet_CreateDirectory_andFullPathIfNeeded(path_name)

How do you name such routines, so it would be clear what does what?



I have come to some my own "convetion" like:

naiveCreateDirectory, ForceDirectoryExists, ...

But I imagine this is very standard situation.

Maybe there already exists some norms/convetions for this?

  • 5
    Usually, when you're asking yourself this question, it's because one method is doing too much. What's wrong with having three methods (leading to if (!DirectoryExists(path_name)) { CreateMissingDirectoriesInPath(path_name); CreateDirectory(path_name); } (actually, in this example, I'd probably try to use recursion to solve the problem, but I don't think that helps you in a more general case.) – pdr Nov 22 '12 at 14:01
  • @pdr If your comment were an answer it would take first spot. The advantage of writing very decsriptive function names is easily being able to tell when things are getting out of control. If doEverythingIncludingThatOtherThing() looks ridiculous, it means 'the system' is working! – MrFox Nov 22 '12 at 20:52
  • @pdr if same 3 commands are repeated over and over (in exactly same maner), then I assume it is a good thing to move that into separate routine.. Isn't it? – dnsmkl Nov 24 '12 at 13:23
  • @dnsmkl: In that case, I'd move it to another class, the class name would specify the technique. Taking the previous example, I'd have an IDirectoryCreator (or DirectoryCreator in Java) interface with a Create(path) method. Then I'd implement that on a MultiLevelDirectoryCreator class. The calling code doesn't need to know about implementation details, it only needs to know that it can create a directory and it has a DirectoryCreator to help it do that, so you can inject the MultiLevelDirectorCreator object via the constructor or fetch it from an IoC Container. – pdr Nov 24 '12 at 14:55
2

There are many possible conventions - I often have to have routines that do something, and other routines that check things and then, eventually, either do it or not. I invariably call these frobWidgets() and maybeFrobWidgets(). There are other prefixes that would fit, e.g. ensure is often used for code that initializes something lazily, but there isn't a universal convention. It's not necessary, though. Far more important than perceived consistency with the "state of the art" is actual consistency within your code base. So go ahead with checkAndFrob() vs. frob() if you've already started doing that.

  • Forth I want to clarify my self. I'm not trying to find latest buzz, just some pre-existing knowledge. Something as design patterns in OO world (e.g. Abstract Factory etc.) – dnsmkl Nov 24 '12 at 13:38
5

If I have a function that may fail - such as creating a directory, writing to a file, etc. - I use the following signature:

bool TryDoSomething(string someParam)

So the method will do something with someParam. If successful, return true; likewise, if unsuccessful, return false.

Method parameters are obviously not always necessary. There is another advantage to this method signature in that you don't have to throw exceptions above this method unless deemed fatal. Note this method can be used to return out values as well. Reference the C# dictionary TryGetValue(...) method.

I also name functions that validate data as SomeParamIsValid(string SomeParam). In this way, I can write something like:

if (SomeParamIsValid(someParam) {
   if(!TryDoSomething(someParam, out SomeObject someObj) {
      // handle failed operation
   }

   return someObj;
}

This makes for some very readable and easily maintained code, in my opinion.

3

Usually function names should be longer when the functions' scope is shorter (ie. private methods) and shorter the name when the functions are public with a longer scope.

In your case, I usually do something like this: createDir($path) and fail with ugly error; or tryCreatingDir($path) and catch the error and continue with an internal decision like throw a nice error message or if the directory already exists suppress all errors and get out as normal.

This does not pollute the naming but does a differentiation. Also the explicit nice user friendly exception message is enough for all the exceptional cases.

Sometimes I invert this and use createDir() to check for stuff and than the second method would be doCreateDir() and I would call it ONLY if all conditions are met to create the directory.

1

Not prefixes, but case. Consider using TurgidCapitalCaseNames() for 'opinionated' functions and brief_lower() names for basic 'raw' functions.

This presumes you can separate your application into 'raw' and 'opinionated' parts. Sort of like what Linux calls policy/mechanism. Then, your question of where to put the decision work to satisfy preconditions answers itself: In the opinionated functions.


    error_type  mkdir_and_parents(string path);
    Dir         MakeAnEmptyOutputDirectory(string subdir);

Mixing identifier case like this disgusts some people, but it might work for you?

By 'opinionated', I mean functions that would be:

  • cock-sure: deluded with the unquestionable reachability of the goal
  • expedient: taking short cuts to success, e.g. succeeding silently if the directory exists already
  • precocious: acquiring needed resources without a second thought, allocating memory, making parent directories
  • stubborn: e.g. retrying while the system responds with 'filesystem full'
  • robust: gets stuff done; might log warnings when someone else is at fault, but probably has a fallback answer

Your 'raw' functions could be quite the opposite:

  • subservient: don't do anything unless asked, and when asked, do only that
  • leaky: make no attempt to cover up the horror, should anything go wrong; Keen to hand problem back to someone else
  • humble: assume no control over any resource not expressly given
  • simple: only knows about a very small range of things

I doubt there is much of a middle ground. It would be very confused ground.

Aside: I think internal subsystem code and system interfaces are usually 'raw'-like. On the other hand I've found most customer-facing 'event response' code is usually very opinionated: eg key command handlers, view renderers, report generators, cron tasks.

Such a correlation might be because it is more important that world-facing parts of the system achieve a robust something instead of a fragile nothing. Maybe it reflects the human or business user's rough needs and expectations, versus the conservative, detail-oriented engineer-artisan's needs for dealing with complexity and diagnosing faults.

  • not sure if I like this convention, but I did enjoy this structured break-up of "raw" vs "opinionated". – dnsmkl Oct 20 '17 at 9:12
0

I'ld go with:

createDirectory(param)
chkDirectoryExists(param)

If these are ambiguous ie if there were two different types of directories I'd split the object in two which would both implement an interface called something like DirectoryHandler.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.