java – Sequential Counter Design question – Education Career Blog

This is more of a design question and my main intention to post here is to get diverse inputs on the problem’s solution.

What I want to create is a counter. A counter maybe single valued (single char / digit) or multivalued. So I’ve designed an hierarchy like this (read Key = Counter) :

                              Key
                               |
      -----------------------------------------------
      |                 |             |              |
SingleValueKey    MultiValueKey   NumericKey   AlphaNumericKey
  (there could be further mix and match between these types)

Now while designing the MultiValueKey, I thought I could simply use a collection of n-SingleValueKey to create a n-character counter. For e.g. a 2 digit (multivalue) counter will use an array of size 2 of SingleValue Numeric counters. What I’m eventually planning is a variable length alpha-numeric key set, base 64, for short urls. The numeric context is just a simple example.

What I’m stuck at now is the “rolling” or “wrapping” of lower order counters into incrementing higher order counters. Foe e.g. for a 2 digit counter, once the units place reaches 9, the next number will be when the units places wraps around to 0 and the tens place is incremented by 1.

I have a few areas I need your feedback on how this should be done :

  1. The single value counters should throw an exception when its reached its max value? Or should it automatically wrap around? Or should it allow the user to specify which of these approaches should be taken?
  2. In case the single counter should throw an exception (as I think), there should be a “reset” method to reset the counter to the start – the caller should handle the exception and call reset (before / after it goes on to increment higher order counters). Would this be a good design?
  3. When the counter is just initialized – new SingleValueNumericKey() – what should be the value of the counter? Should it be ready to use, with no value, OR should it be the first value in its value set?
  4. Similar to the prev question, when the “reset” method has been called, what should be the value of the counter?

Please help me with your valuable inputs here. If you have suggestions on the design itself, its more than welcome! If I take away something from this thread, I’m going to refer to it in my commits – so you will have the credit for the suggestion 🙂

Thanks,
Madhur Tanwani

EDIT: Added my final use case to clarify Jason’s questions for all.

,

Design each counter to know about the higher order counters, so you only have to interact with the counter in the ones place. You can use a constructor with a specified number of digits to create the higher order counter with one less digit. When you increment the counter, you can compare this to the base being used (number of values per digit) and reset to zero and increment the higher counter. Getting the value can also be done recursively.

It’s good to do this design without exceptions. Exceptions should be used when there is an exceptional circumstance, beyond what is normally expected. For example, when a file read fails, or a network socket won’t connect. You shouldn’t use exceptions for normal events like a counter rolling.

The reset method should set all counters back to zero, and this is the default value they should have when they are initialized. In fact, the reset method can use the same linking so that when you call reset on a counter, it will reset its value to zero and call reset on its higher counter, if set.

You can build on this same design to abstract away concepts like the specific characters used to represent each value. You can also make a function to get the whole counter set as a string, recursively, using an abstract function for the character for each value so that you can subclass it like you designed.

public class Key {
  private Key higherKey;
  private int base;
  private int value;

  public Key(int base, int numberOfDigits) {
    this.base = base;
    if (numberOFDigits > 1)
      this.higherKey = new Key(base, numberOfDigits - 1);
    this.value = 0;
  }

  public int getNumericValue() {
    int value = this.value;
    if (this.higherKey != null)
      value += (this.higherKey.getValue() * this.base);
    return value;
  }

  public void increment() {
    this.value++;
    if (this.value >= this.base) {
      this.value++;
      if (this.higherKey != null)
        this.higherKey.increment();
    }
  }
}

,

Do yourself a favor and create some use cases, so it’s clear what you need. If you’re just talking about N-digit numerical counters, what you have seems like overkill. But maybe not.

Leave a Comment