Как избежать иерархии параллельного наследования в API / библиотеке

gridDragon спросил: 13 октября 2017 в 06:32 в: java

Я работаю над библиотекой шифрования, чтобы упростить использование моей командой шифрования для учетных данных API и получения зашифрованных сообщений от других команд / проектов.

Я начал с этих интерфейсов верхнего уровня, чтобы определить домен

public interface Key {
    public byte[] getBytes();
}public interface Message {
    public byte[] getBytes();
}public interface Secret {
    public byte[] getBytes();
}public interface Decrypter {
    public String decrypt(Secret secret, Key key);
}public interface Encrypter {
    public Secret encrypt(Message message, Key key);
}

Это помогло обернуть шифрование RSA:

public class KeyPair {
    private final Key publicKey;
    private final Key privateKey;    public Key getPublicKey() {
        return publicKey;
    }    public Key getPrivateKey() {
        return privateKey;
    }
}public class RsaEncrypter implements Encrypter {    @Override
    public Secret encrypt(Message message, Key publicKey) {
        // Perform Encryption
    }
}public class RsaDecrypter implements Decrypter {
    @Override
    public String decrypt(Secret secret, Key privateKey) {
        // Perform the decryption
    }
}

Но теперь я применяю его для нашего использования шифрования AES. случаи я столкнулся с проблемой. Секрет содержит InitializationVector, потому что мы используем AES в режиме CBC.

Итак, у меня есть это:

public class AesSecret implements Secret {
    private byte[] cipherText;
    private byte[] initilizationVector;    @Override
    public byte[] getBytes() {
        return cipherText;
    }    public byte[] getInitilizationVector() {
        return initilizationVector;
    }
}public class AesDecrypter implements Decrypter {
    @Override
    public String decrypt(Secret secret, Key key) {
        try {
            return decrypt((AesSecret) secret, key);
        } catch (ClassCastException e) {
            throw new IllegalArgumentException("AesDecrypter only supports subclasses of AesSecret", e);
        }
    }    public String decrypt(AesSecret secret, Key key) {
        // Do the AES Decryption
    }
}

ClassCastException заставляет меня думать, что я Я нарушаю принцип подстановки Лискова и вводим параллельную иерархию кода-запаха. Я читал, что шаблон Visitor является распространенным решением для этого запаха кода, но я не выяснил, как он будет применяться к моей ситуации.

Есть предложения? Или я слишком обдумывал это?

Я добавил эти классы в Gist: https://gist.github.com/mmeier/c493c28cbcd57a73d08419066cd23484


0 ответов