52

I have run into a corner-case problem with the general guidance of:

  • nouns for variables
  • verbs for functions

Specifically, I have a case where the word is ambiguous - it can be either a verb or a noun. And in some cases when we're discussing the application, it will be used both ways in the same sentence.

My intent is to make sure the program will remain readable to future developers as well as myself when I return to sections of code months later.

One of the examples is with a battery. A battery has a charge and you can also charge() a battery.

I think that having both Battery.Charge and Battery.Charge(value) will be confusing to future developers.

My current solution is to simply pick a different word for one or both of those cases (the variable and the function). My problem with that approach is the Battery object's variable and function for charge won't align with design discussions involving the Battery.

My question is if there is another / better way to handle this conflict in naming convention?


Some additional reading on the subject. None really addressed the particular of my question.

  • 3
    make the charging function addCharge easy and clear enough – ratchet freak Jan 25 '13 at 19:47
  • 2
    Could you prefix the noun variable with "Current-"? So "CurrentCharge" vs "Charge()"? – Brian Snow Jan 25 '13 at 19:53
  • @BrianSnow - that's in alignment with what ratchet freak is suggesting as well. I hadn't really considered adding a sense of time to the variable since everything with the `Battery` object is "current." –  Jan 25 '13 at 19:59
  • @ratchetfreak - that fails my symmetry test since I have a `Discharge()` function as well. ;-) Good suggestion though, and that's in alignment with what I'm planning on doing. –  Jan 25 '13 at 20:00
  • 6
    or just ChargeLevel to get the current charge – ratchet freak Jan 25 '13 at 20:27
  • 5
    Make up a word. WordNet doesn't think `enqueue` is a word, but its a verb in Java. How about `doCharge`? It will still fail symmetry test because your other methods will not have this prefix – Miserable Variable Jan 25 '13 at 20:38
  • 1
    @BrianSnow When dealing with batteries, I'd avoid the word [current](http://en.wikipedia.org/wiki/Electric_current).. – Izkata Jan 25 '13 at 23:10
  • 5
    "Current" = now, or "current" = flow of charge. The only real solution is to replace English with a more sensible language! – DarenW Jan 26 '13 at 03:26
  • @DarenW & @ Izkata: Fair enough! – Brian Snow Jan 26 '13 at 05:27
  • It remains irritating anyhow as long as you stick to the bad practice of starting function names with upper case letters. For Germans, for example, an upper case first letter signals a noun or a name, for Haskell programmers, it's a type or constructor. – Ingo Jan 26 '13 at 18:54
  • @Ingo - I wasn't aware of that. Regrettably, in this case, our coding standing requires all public variables and properties to start with uppercase as well as all function names. Very much driven my English language semantics. :-) –  Jan 27 '13 at 01:10
  • 1
    Should I bring up functional languages where functions are both noun and verb or would a head explode? – Erik Reppen Mar 09 '13 at 02:13
  • I would have named the noun `powerLevel` and the verb `setPowerLevel()` – tvanc Apr 23 '19 at 14:26

9 Answers9

42

In similar situations I try to find synonyms. In this case I would use "recharge" for the verb. The "re-" is slightly redundant, but the meaning is clear. Using the simple "charge" for the remaining charge in the battery is ambiguous because it doesn't specify any physical units. I would prefer "availableAmpHours", "hoursUntilRecharge" or something similar. The units will depend on whatever is convenient for the application.

My personal preference is to use verbs only for functions that change state. I use nouns for non-mutating functions. I suppose it depends on your point of view. At the machine level, non-mutating functions do something, but at the model level, they don't.

kevin cline
  • 33,608
  • 3
  • 71
  • 142
  • 2
    Excellent point on the units. Units are explicitly left off in this case because they can change depending upon the analysis we're running. Ie, we're using different time scales and the Battery adjusts its operations in terms of the analysis' scale. –  Jan 25 '13 at 20:10
  • 1
    I prefer verbs for expensive, non-mutating functions. E.g., functions that run a query on a database. – Brian Mar 08 '13 at 21:55
  • Another case where `charge` not having any units would make sense would be if it returned a value object of `Charge` type. That could have functions on it like `inColoumbs`, `inAmpHours`, `inMilliAmpHours` that would each return floats. – bdsl Oct 10 '21 at 22:36
22

Just throwing this out there, but maybe the solution for this instance of naming ambiguity is to remove that functionality from the battery entirely. I've never seen a self charging battery and it would make more sense to me to have a BatteryCharger class. This would help keep your concerns more decoupled and make the action more explicit.

battery.Charge(50) vs batteryCharger.Charge(battery, 50)

To me, the second form is much more understandable and keeps all your "Charging" code in one place rather than sprinkling it throughout all your battery classes.

samthebrand
  • 368
  • 2
  • 12
  • 27
mortalapeman
  • 1,613
  • 9
  • 20
  • 7
    It's not a bad thought, but in this case `Battery` is an abstraction for the battery + charging system. Our app doesn't require breaking the two aspects out into separate objects, so they are rolled into one (aka `Battery`) for convenience. Ultimately, the physics of a chargeable battery dictate that it has some sort of function to accept a charge. –  Jan 27 '13 at 01:12
  • In that case, I submit that kevin cline's answer is what you are looking for. For clarity, I would use Recharge and Discharge for the mutating functions and Charge for the property name. Perhaps ChargePercent would be a good one as well. – mortalapeman Jan 27 '13 at 02:02
  • Are you perhaps a Java programmer? This is clearly a violation of Don't Repeat Yourself. In fact, you're repeating EVERYTHING except the parameter "50". I couldn't come up with a worse example of a DRY violation if I tried. – boxed Mar 11 '13 at 08:47
  • @boxed Are you taking about my example? Because I am not sure how you can claim I am violating DRY when I have no implementation. I am a huge proponent of SOLID principles and am just not seeing how you came to that conclusion. – mortalapeman Mar 11 '13 at 16:08
  • You are violating DRY by creating an unnecessary BatteryCharger class that will somehow then cause a state change in the Battery. So BatteryCharger will accept some input that it will then immediately pass on to Battery. – kevin cline Mar 13 '13 at 20:08
  • @kevincline You are assuming that my implementation modifies the state of my battery. Perhaps it performs more of a factory operation where a new battery is created from the old battery and the charge value. Perhaps there is some base unit that battery uses for charge and the battery charger is reponsible for converting the input to this value and setting the battery's charge. Without knowing the implementation you can not know if my example is DRY or not. – mortalapeman Mar 13 '13 at 21:23
10

Avoid Double Meanings

You have deliberately selected a word that has more then one meaning, and that first decision is the problem. There are a ton of words that are problematic for programmers. Another example would be phone. You can phone someone, or you could have a phone in your pocket.

Use Getters and Setters

The standard naming for most objects is the getters/settings methods for properties.

Battery.Charge            // would be a property
Battery.setCharge(value)  // would set the property
Battery.getCharge()       // would get the property

Properties Are States Not Nouns

I think you are mistaken by classifying object properties as nouns, and variables could also be thought of states. They are states relevant to the local scope of their existence.

You could describe the value that they hold as a noun, but I'm not sure that is true in all cases.

In OOP terminology object properties describe the state of that object. In your case the Battery is an object, and it's Charge is a state. So that would be a property of the object, but this depends on the context of how it's used.

If you need to be able to Charge the battery, and also know what it's current Charge is, then you have a problem.

Using Scope To Enforce Context

Context is what will clarify which meaning of a word you intend a method or property to convey. Scope is setting the accessibility of a property/method from outside the object.

Batter._charge            // a hidden private property
Battery.setCharge(value)  // would set the private property
Battery.getCharge()       // would get the private property
Battery.Charge()          // would perform the Charge action

Methods Are Verbs

You can describe the method of an object as a verb, but the word action is better suited. In OOP terminology you perform actions upon objects using their methods. It's bad form to modify an object's property from outside the object. It's preferred to call a method that performs the actions required that causes it's state to change.

The word Charge is a verb, but it's also a noun. When used to call the method of an action it becomes clear that the verb is being used Battery.Charge(....).

But, context is very important. While the word Charge() is a verb it's not as meaningful as startCharging().

Valid methods for Battery could include Charging, Discharging, setCharge, getCharge, hasCharge, Discharge and Charged.

Simple one word methods often don't explicitly state their actions clearly, but there are some cases like open and close where little explaining is required.

So there isn't really a correct answer as to how to name these types of properties/methods. Except that you need to use the above techniques wisely to ensure there is no confusion.

Reactgular
  • 13,040
  • 4
  • 48
  • 81
  • 2
    For the record, the client is the one who is using the ambiguous terminology. **I** didn't create that mess. :-) I brought the question up since I thought I may not be the only person walking into such a situation. You have some valid points in your answer. In this particular case, we're not working at the granularity of time that `StartCharge()` and `EndCharge()` would imply. In fact, that terminology would add significant overhead to handling the battery system. At each interval it can either `Charge()` or `Discharge()`. –  Jan 27 '13 at 01:19
  • 2
    The primary struggle is in keeping internal programming semantics synchronous with the terminology that the client is using. `Charge` happens to be the most readily understood ambiguous word for this domain. There are several others. –  Jan 27 '13 at 01:20
6

Prepend them with verbs that will make them a verb or a noun.

Battery.doCharge()

Battery.getCharge()
Jürgen Paul
  • 260
  • 2
  • 7
5

For the verb case, I think Charge is OK. For the noun case, would getCurrentChargeLevel work for you?

FrustratedWithFormsDesigner
  • 46,105
  • 7
  • 126
  • 176
  • Not sure on that. Since we're using C#, we can declare the get and set on the Property instead of needing separate functions. Irrespective of that, I'm concerned about maintenance and how it will look once I've forgotten what I wrote. Wouldn't `getCurrentChargeLevel()` would still need to refer to an internal variable of `Battery`, and what would the name of that variable be? –  Jan 25 '13 at 19:49
  • is charge a voltage or a percentage? – mhoran_psprep Jan 25 '13 at 19:52
  • 1
    @GlenH7: Ah, I see. You didn't specify C# and my brain is in Java mode. Well either way, I think that for the noun representing the amount of charge currently in the battery, something along the lines of `Battery.currentChargeLevel` might work. You could try using `Battery.coloumbs` or `Battery.ampereHours` but that might not be as obvious... – FrustratedWithFormsDesigner Jan 25 '13 at 19:59
  • 1
    @mhoran_psprep - neither. ;-) `Charge` is `Energy` which is `Power` (Volts * Amps == Watts) multiplied by time. So in this case, charge is a number. There is also a state of charge which happens to be a percent. –  Jan 25 '13 at 20:03
  • @FrustratedWithFormsDesigner - yes, I left C# out since I thought the broader corner case was applicable regardless of language. `Watt*time` definitely wouldn't align with design conversations, but `ChargeLevel` would. –  Jan 25 '13 at 20:05
0

In most cases adding a helping verb, adverb, or adjective is good enough to distinguish them and can actually help with understanding. With your case of Charge and Charge() on a battery making it DeltaCharge() could show that it's a function that can handle either charging or discharging.

Delta (in cases where there's a change but ambiguous) is a modifier that I use and recommend to others all the time for handing change in state (even if the verb is semi-obvious).

Jeff Langemeier
  • 1,397
  • 9
  • 19
0

Hungarian Notation to the rescue. You can have intCharge and fcnCharge(value), thus avoiding confusion and not adding a crazy long name when three letters will work just fine.

Or you could just use the same name and let the IDE handle it. Creating a longer or different name may be just as confusing in the long run anyway.

samthebrand
  • 368
  • 2
  • 12
  • 27
Ryathal
  • 13,317
  • 1
  • 33
  • 48
  • +1 for the unique perspective on the answer. Regrettably, Hungarian notation is explicitly verboten per our code style guidelines. That doesn't change the potential merit of your answer, just that I can't use it as my actual solution. –  Jan 25 '13 at 21:58
0

How about a coding convention for fields?

// C++
class Battery
{
private:
    T _charge{};  //  or m_charge or charge_
public:
    charge( Time length, Current max_current );
}
Vorac
  • 7,073
  • 7
  • 38
  • 58
0

You need different words for both meanings of “charge”. StartCharging and ChargeLevel will do. If you change only one word, someone will call Charge() when they actually wanted to call the other one.

gnasher729
  • 42,090
  • 4
  • 59
  • 119