6

Consider that I have Algorithm enum as

public enum Algorithm {
  SHA1("sha1"),
  HMAC("hmac"),;

  Algorithm(final String algorithm) {
    this.algorithm = algorithm;
  }
  private final String algorithm;

  public String getAlgorithm() {
    return algorithm;
  }
}

and I have different algorithms as

public class Sha1 {
   public static String hash(final String text, final byte[] sb) {...}
}

and

public class Hmac {
   public static String hash(final String text, final byte[] sb) {...}
}

I want to return their instances when someone calls for example

Algorithm.SHA1.getInstance()

Question

  • How can I return the instance since my method is static? (It is static so that multiple threads can not play around with each other data)
Yohn
  • 580
  • 5
  • 19
daydreamer
  • 87,243
  • 191
  • 450
  • 722
  • To making it thread safe - what about using synchronization? – Razib May 20 '15 at 02:14
  • The same way you add a getAlgorithm() method you can also add a getInstance() method. You can implement that on the Enum or on the different ciphers. `SHA1("sha1") { X getInstance() { return new Sha1(); }, Hmac("hmac") { X getInstance() { return new Hmac(); }` (but that does not help you much with a static method - which is not a good idea in that case anyway). – eckes May 20 '15 at 04:14

1 Answers1

6

You can't return an instance when your method is static, but you can make your enum implement an interface, and make an instance method that calls the static method perform the virtual dispatch for you:

public interface EncryptionAlgo {
    String hash(final String text, final byte[] sb);
}

public enum Algorithm implements EncryptionAlgo {
    SHA1("sha1") {
        public String hash(final String text, final byte[] sb) {
            return Sha1.hash(text, sb);
        }
    },
    HMAC("hmac") {
        public String hash(final String text, final byte[] sb) {
            return Hmac.hash(text, sb);
        }
    };

    Algorithm(final String algorithm) {
        this.algorithm = algorithm;
    }
    private final String algorithm;

    public String getAlgorithm() {
        return algorithm;
    }
}

Now you can call hash on the SHA1 or HMAC instance, like this:

Algorithm.HMAC.hash(someText, sb);

or pass around EncryptionAlgo instances, like this:

EncryptionAlgo algo = Algorithm.SHA1;
Community
  • 1
  • 1
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Well, `Algorithm` *could* contain static instances of both `Sha1` and `Hmac` and return one or the other, assuming that both those classes implement the `EncryptionAlgo` interface. But making `Algorithm` *itself* implement the interface seems better, since it avoids the need to call `getInstance()`. An enum instance is already a static singleton, so it's stilly to use one just to look up *another* static singleton. – Wyzard May 20 '15 at 02:20
  • 1
    Also, SHA1 and HMAC are hash functions, not encryption algorithms. The `EncryptionAlgo` interface would be better named something like `HashFunction`. – Wyzard May 20 '15 at 02:21
  • You don't actually need the interface. You can just have the method on the enum type directly. – Louis Wasserman May 20 '15 at 06:21