I have created an Encryption and Decryption Algorithm that encrypts plain text using a given cipher and also decrypts it back to the original notation. It works great.
This was my code for a coding test and the reviewer told me that the class structure is inverse of what is the right way of doing it and that it is sloppy at some places.
I want to know what is wrong with my structuring of classes, if anything. Does it look sloppy? Can someone please help me identify places where it is lacking Best Practices for Java?
I have a MyBuilder
class which creates an instance of MyAlgorithm
.
MyAlgorithm
has the methods to encrypt and decrypt text, and it extends another class called EncryptionAndDecryption
where the actual logic of the algorithm resides.
public class MyAlgorithm extends EncryptionAndDecryption {
public enum Action {
ENCRYPT,
DECRYPT
}
protected MyAlgorithm(final String cipherCharSet) {
super(cipherCharSet);
}
public String encryptText(final String cipher, final String plainText) {
return encryptOrDecryptText(cipher, plainText, Action.ENCRYPT);
}
public String decryptText(String cipher, String encryptedText) {
return encryptOrDecryptText(cipher, encryptedText, Action.DECRYPT);
}
public boolean encryptDirectory(String cipher, String baseDirectory) {
// for each files and sub files in each sub directories, call the following method;
// encryptOrDecryptFile(cipher, file, baseDirectory, Action.ENCRYPT));
}
public boolean decryptDirectory(String cipher, String baseDirectory) {
// for each files and sub files in each sub directories, call the following method;
// encryptOrDecryptFile(cipher, file, baseDirectory, Action.DECRYPT));
}
}
public class EncryptionAndDecryption {
private final String CIPHER_CHAR_SET;
protected EncryptionAndDecryption(final String cipherCharSet) {
this.CIPHER_CHAR_SET = cipherCharSet;
}
protected final String encryptOrDecryptText(final String cipher, final String inputText, final MyAlgorithm.Action action) {
// method logic here
}
protected final void encryptOrDecryptFile(final String cipher, final Path filePath, final String baseDirectory, final MyAlgorithm.Action action) {
// method logic here
}
}
public class MyBuilder {
private String CIPHER_CHAR_SET;
private MyBuilder() {}
public static MyBuilder builder() {
return new MyBuilder();
}
public MyBuilder withCipherSet(String cipherSet) {
this.CIPHER_CHAR_SET = cipherSet;
return this;
}
public MyAlgorithm build() {
return new MyAlgorithm(CIPHER_CHAR_SET);
}
}
public class MyEncryptionApp {
public static final String CIPHER_CHAR_SET = "abcdefghijklmnopqrstuvwxyz";
public static void main(String args[]) {
if (args.length != 3) {
System.out.println("Exact 3 parameters required - [action] [key] [target]");
System.exit(1);
}
String action, key, target;
action = args[0];
key = args[1];
target = args[2];
MyAlgorithm myAlgorithm = MyBuilder.builder()
.withCipherSet(CIPHER_CHAR_SET)
.build();
if ("encrypt".equalsIgnoreCase(action)) {
System.out.println(myAlgorithm.encryptText(key, target));
} else if ("decrypt".equalsIgnoreCase(action)) {
System.out.println(myAlgorithm.decryptText(key, target));
} else if ("encryptDir".equalsIgnoreCase(action)) {
if(myAlgorithm.encryptDirectory(key, target)) {
System.out.println("Directory encryption Successful");
}
} else if ("decryptDir".equalsIgnoreCase(action)) {
if(myAlgorithm.decryptDirectory(key, target)) {
System.out.println("Directory decryption Successful");
}
} else {
System.out.println("action [" + action + "] not implemented");
}
}
}