I implemented the Caesar Cipher in Java, and I wanted to practice MVC.
This is my model:
package biz.tugay.caesarcipher;
import java.util.Locale;
/*
Encyrpts a clear text using Caeser Cipher (https://en.wikipedia.org/wiki/Caesar_cipher)
with given shift amount.
Provided shift amount (i.e. key) must be a positive integer less than 26.
Only English alphabet is supported and encyrpted text will be in uppercase.
Shift amount 0 will return the same clear text.
*/
public final class CaesarCipher {
private String clearText;
private int key;
public String encryptText() {
final StringBuilder cipherTextBuilder = new StringBuilder();
final String clearTextUpperCase = clearText.toUpperCase(Locale.US);
final char[] clearTextUpperCaseCharArray = clearTextUpperCase.toCharArray();
for (final char c : clearTextUpperCaseCharArray) {
if (c < 65 || c > 90) { // If the character is not between A .. Z, append white space.
cipherTextBuilder.append(" ");
continue;
}
final Character encryptedCharacter = encryptCharacter(c);
cipherTextBuilder.append(encryptedCharacter);
}
return cipherTextBuilder.toString();
}
private Character encryptCharacter(final char c) {
final int initialShift = c + key;
final int finalShift;
if (initialShift > 90) {
// This is the case where we go beyond Z, we must cycle back to A.
finalShift = (initialShift % 90) + 64;
} else {
// We are in the boundries so no need to cycle..
finalShift = initialShift;
}
return (char) finalShift;
}
public void setClearText(String clearText) {
this.clearText = clearText;
}
public void setKey(int key) {
this.key = key;
}
}
My View:
package biz.tugay;
import java.util.Scanner;
public class CaesarCipherView {
public String askForClearText() {
System.out.println("Please enter clear text: ");
final String clearText = new Scanner(System.in).nextLine();
return clearText;
}
public int askForKey() {
System.out.println("Please enter a positive integer number between 1 - 25");
final int key = new Scanner(System.in).nextInt();
return key;
}
public void warnUser() {
System.out.println("Please enter a valid key value!");
}
public void presentEncrpytedText(String encryptText) {
System.out.println("Here is your encrypted text: ");
System.out.println(encryptText);
}
}
The controller:
package biz.tugay;
import biz.tugay.caesarcipher.CaesarCipher;
public class CaesarCipherController {
private final CaesarCipherView caesarCipherView;
private final CaesarCipher caesarCipher;
public CaesarCipherController(final CaesarCipherView caesarCipherView, final CaesarCipher caesarCipher) {
this.caesarCipherView = caesarCipherView;
this.caesarCipher = caesarCipher;
}
public void getClearTextFromUser() {
String clearText = caesarCipherView.askForClearText();
caesarCipher.setClearText(clearText);
}
public void getCipherKeyFromUser() {
int key;
try {
key = caesarCipherView.askForKey();
if (key < 1 || key > 26) {
caesarCipherView.warnUser();
getCipherKeyFromUser();
} else {
caesarCipher.setKey(key);
}
} catch (Exception e) {
caesarCipherView.warnUser();
getCipherKeyFromUser();
}
}
public void encryptAndPresent(){
final String encryptText = caesarCipher.encryptText();
caesarCipherView.presentEncrpytedText(encryptText);
}
}
This is how I bootstrap my application:
package biz.tugay;
import biz.tugay.caesarcipher.CaesarCipher;
public class App {
public static void main(String[] args) {
final CaesarCipher caesarCipher = new CaesarCipher();
final CaesarCipherView caesarCipherView = new CaesarCipherView();
final CaesarCipherController caesarCipherController = new CaesarCipherController(caesarCipherView, caesarCipher);
while (true) {
caesarCipherController.getClearTextFromUser();
caesarCipherController.getCipherKeyFromUser();
caesarCipherController.encryptAndPresent();
}
}
}
Here is a sample run:
Please enter clear text: KORAY TUGAY Please enter a positive integer
number between 1 - 25 0 Please enter a valid key value! Please enter a
positive integer number between 1 - 25 2 Here is your encrypted text:
MQTCA VWICA Please enter clear text:
Is my understanding of Model View Controller correct? Should the controller do the encryption? Do I need a separate model?