Question

I have had hard times naming boolean fields.

On the one hand, i've read that it is good to name them as affirmative statements, like hasAge, or canDance. It's not a problem when naming local variables, for example

boolean itemIsActive;
boolean everyItemHasName;

But i don't see how these rules could apply this to field name

Let's assume that in our project user can define multiple currencies, and determine which one of them is the default one.

class Currency {
  String name;
  boolean myProblematicVariable; // this variable should say 'I AM or I AM NOT the default currency'
}

How would you name myProblematicVariable? I have few types but none of them seems right

  • default - Taking aside the fact that it's a keyword in many languages (that's not the point of this discussion), i like the fact that if we are using standard getters then i can write boolean currencyIsDefault = currency.isDefault(). Hovewer, it's not affirmative.
  • isDefault - My next guess, but it's standard getter and setter looks the same as it would look for field named default. This is a problem when it comes to serialization/deserialization, for example .: Java's jackson (json serialization/deserialization library) will serialize this
class Test {
  private boolean isActive = true;

  public boolean isActive() {
    return this.isActive;
  }

  public void setActive(boolean isActive) {
    this.isActive = isActive;
  }
}

as this

{"active":true}

And this is true for all serialization/deserialization libraries operating on getters and setters. This creates confusion and inconsistency between, for example, how dto looks on the server and client side. I could, ofcourse tell jackson that "This field is named isActive" using annotation, but this seems like a hack used to repair bad design.

  • currencyIsDefault - seems kinda right, but feels too much. I mean, what's the point of using currency as part of it's field's name, that comest from context. And imagine writing boolean currencyIsDefault = currency.isCurrencyIsDefault(). Awful.

And please don't stick to single language standards, assume that Currency is DTO which can be sent between client and server.

Edit

Some ground rules .:

  • Only one currency at a time can be default
  • This discussion is not about design patterns but strictly about field naming. Instead of determining whenever the currency is default it could be whenever it's active, enabled, archived, maybe hovered (in gui application) or really, anything else that comes to your mind.
Was it helpful?

Solution

The X problem

I think we're dealing with an XY problem here, as your question is trying to implement something that should've been fixed another way.

Let's assume that in our project user can define multiple currencies, and determine which one of them is the default one.

The choice of your application's default currency should not be contained in the currency class itself. The currency class (and any object of this type) only cares about its personal data (e.g. name, currency symbol, format, ...)

Which currency is the default is not a setting that is specific to a given currency, it's a setting that is specific to the current application (or e.g. a user, if your users can have different default currencies set).

Think of it this way: what happens when more than one currency claims it is the default? Your likely response is "well that shouldn't happen, the application should only set one currency as the default", and that proves my point that the application is the one who manages this information, not the currency itself.

You should not be doing this:

class Currency
{
    public bool IsDefault { get; set; }
}

You should be setting the default on a scope that is appropriate to the application. One simple example (out of many possible options):

static class ApplicationSettings
{
   public static Currency USD = new Currency("USD", "dollar", "$");
   public static Currency EUR = new Currency("EUR", "euro", "€");
   public static Currency GBP = new Currency("GBP", "pound", "£");

   public static Currency DefaultCurrency = ApplicationSettings.USD;
}

I used a static example because it's the shortest complete example I could think of that highlights the point I'm making. Like I said, there are many possible approaches.
The main takeaway here is that the selection of the default currency happens outside of the Currency class itself.

Not only does this ensure that the decision is made at the appropriate level, it also prevents the issue with possible having multiple default currencies, since it's now actually impossible to have more than one value set as the default currency.

This means we're dealing with an XY problem, and your posted question (Y) becomes moot.

However, the rest of the answer will still answer your posted question (Y). You posted a well-formed question which suggests it's something you do want an answer to in general, not just for this specific scenario. It just doesn't quite fit for the scenario that prompted you to ask the question in the first place.


Affirmative phrasing

i can write boolean currencyIsDefault = currency.isDefault(). Hovewer, it's not affirmative.

This is actually affirmative.

In this context, "affirmative" means "not negative". isNotDefault is an example of something that's not affirmative, i.e. negative.

Similarly, isDead and isAlive are both affirmative - even though they are opposite. isNotDead and isNotAlive are not affirmative.

The reason this rule exists is to avoid double negations. If you use negatively defined boolean such as isNotDead, then you mean end up writing code like:

if(!isNotDead)
{
     Console.WriteLine("I am alive");
}

Which is really hard to read because of the double negation.

In case you didn't notice yet, the console message is wrong, the subject is actually not alive but dead (!isNotDead is equal to isDead). The fact that you probably did not catch this immediately proves the readability issue.

But i don't see how these rules could apply this to field name

Whether something is a variable or a field is a consideration that is entirely separate from the meaning of a value (and thus the name it should have to portray that meaning). I'm not sure how you come to the conclusion that you can't use the same naming approach.


Your suggestions

  • default

I would expect a field named default to contain the default value itself, not a confirmation on whether this object is the default value or not.

boolean itemIsActive;

Note that "item" is optional here. If the code (in which the local variable is declared) makes it clear that you're working with an item, you don't need to specify that in the local variable name. Take the following example:

public void DescribeItem(Item i)
{
    bool isActive = (i.Status != Status.Inactive);

    if(isActive)
    {
        Console.WriteLine("This is an active item!");
    }
    else
    {
        Console.WriteLine("This is an inactive item!");
    }
}

There's no readability improvement from using itemIsActive over isActive. However, if the code was handling multiple objects, then it does become relevant to specify that this boolean labels the activeness (activity?) of the item as opposed to another object.

  • currencyIsDefault

I established the point that "item" can be optional, because of the following consideration: when dealing with class fields/properties, it's always obviously in scope of the current object.

Therefore, the isDefault property of the Currency class is always understood to mean thisCurrencyIsDefault, and therefore you don't have to specify it any more than isDefault already does.

  • isDefault

This is the correct approach. It allows for readable object-based access (myCurrency.IsDefault), it semantically describes the object in question, and it makes it clear that this field contains confirmation on something being a default, rather than the default value itself.


Note
There's a conflict in considering whether isDefault should be the field or the setter method. Ideally, it should be both, but that's impossible in Java due to the lack of class properties. That's a language-specific issue, and you should solve it using conventional Java standards and practices. Personally, I'd go with isDefault for the field and setDefault for the setter, but I'm a C# dev and unsure if this is the conventional Java syntax.

You asked for a language-agnostic answer, so I have avoided a Java-specific answer except for this last note.

OTHER TIPS

I think your trouble is that you're looking only at the field name to judge name quality. But the public interface of your class contains the field name and the field type.

In my view, a Boolean field called default says exactly what it has to say. If it were a method, I'd want to know whether this method computes the default, sets the default (and to what?), or whether it changes the default currency. If it were a string it might be the name of the default currency, or the default name of this currency. But as a Boolean field, the meaning pretty much can only be "does this object represent the unique default currency or not?".

When specifying Java beans, says the "is" should be with the boolean variable. So something that can be formed with "is":

Generate Getters and Setters in Eclipse dialog

If you call the variable defaultCurrency, it comes out as follows:

public class Currency {
    private boolean defaultCurrency;
    private String name;

    public boolean isDefaultCurrency() {
        return defaultCurrency;
    }

    public void setDefaultCurrency(boolean defaultCurrency) {
        this.defaultCurrency = defaultCurrency;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Regardless, I wouldn't have many objects, and each has a property “I'm the default” (what do you do if more than one says “I am”) but on a higher level, the application has a default currency, and then pointing to Currency.

public class Config {
    private Currency defaultCurrency;
}

public class Currency {
    private String name;
}

isDefault is the same as hasAge and canDance - they all work as questions when you are getting the value, and statements when setting the value.

if (myCurrency.isDefault)   // makes sense

myCurrency.isDefault = true; // also makes sense

From my point of view you do not have a problem with naming your variables but more a problem of general software design. Your problem is typical for a so called Strategy Pattern.

Try to separate the concerns. At the moment your currency class has two concerns:

  • Validating if it is the default currency
  • Holding currency-specific properties

The following code sample is an example of how to use strategy:

class Currency {
    name: string;
}

class DefaultConfiguration {
    defaultCurrency: Currency;
}

class User {
    currency: Currency;
}

isDefaultCurrency is perfectly fine if this is a property that is true for one currency and false for all others.

But we don’t know that. Before you pick a name, specify precisely what the property means, and only then we can talk.

As edited, "isDefaultCurrency" is perfectly fine. From a development point of view, I might not have this property at all, but have a class property "defaultCurrency" of type Currency, which returns nil or the default currency. That makes it easier to change. On the other hand, if you have "German Euro" and "French Euro" as separate currencies, and they can both be the default currency at the same time, then it would be a property of the currency (this would be strange though).

Licensed under: CC-BY-SA with attribution
scroll top