- Published on
CS 3500 Day 8
- Authors
 - Name
- Jacob Aronoff
 
 
Object Oriented Design
Today we're getting back to the calculator controller and model we were working on last time:
package cs3500.lec08;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.Scanner;
/**
 * Demonstrates a simple command-line-based calculator
 */
public class SimpleCalc1 {
  public static void main(String[] args) {
    Calculator model = new Calculator();
    CalcController controller = new CalcController(model);
    controller.go();
  }
}
class CalcController {
  private final Calculator model;
  private InputStream input;
  private PrintStream output;
  public CalcController(Calculator model) {
    this.model = model;
    this.input = System.in;
    this.output = System.out;
  }
  public CalcController(Calculator model, InputStream input, PrintStream output) {
    this.model = model;
    this.input = input;
    this.output = output;
  }
  public void go() {
    int num1, num2;
    Scanner scan = new Scanner(input);
    output.println("Enter a number: ");
    num1 = scan.nextInt();
    output.println("Enter another number: ");
    num2 = scan.nextInt();
    output.printf("The answer is: %d", model.add(num1, num2));
  }
}
class Calculator {
  public int add(int num1, int num2) {
    return num1 + num2;
  }
}
And the tests we wrote:
package cs3500.lec08;
import org.junit.Test;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import static org.junit.Assert.*;
/**
 * Created by jea on 1/31/17.
 */
public class CalcControllerTest {
  @Test
  public void go() throws Exception {
    Calculator model = new Calculator();
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    PrintStream printStream = new PrintStream(baos);
    ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream("6\n 8\n".getBytes());
    CalcController controller = new CalcController(model, byteArrayInputStream, printStream);
    controller.go();
    assertEquals(baos.toString(), "Enter a number: \n"
            + "Enter another number: \n"
            + "The answer is: 14");
  }
}
Now we have to change the Controller such that it uses the Appendable and Readable interfaces. This is a pretty simple change:
class CalcController {
  private Readable input;
  private Appendable output;
  public CalcController() {
    this.input = new InputStreamReader(System.in);
    this.output = System.out;
  }
  public CalcController(Readable input, Appendable output) {
    this.input = input;
    this.output = output;
  }
  public void go(Calculator model) throws IOException {
    int num1, num2;
    Scanner scan = new Scanner(input);
    this.output.append("Enter a number: \n");
    num1 = scan.nextInt();
    this.output.append("Enter another number: \n");
    num2 = scan.nextInt();
    this.output.append(String.format("The answer is: %d", model.add(num1, num2)));
  }
}
Now we have to change our test to match that:
public class CalcControllerTest {
  StringBuffer stringBuffer;
  StringReader stringreader;
  CalcController controller;
  @Before
  public void setup(){
    stringBuffer = new StringBuffer();
    stringreader = new StringReader("6\n 8\n");
    controller = new CalcController(stringreader, stringBuffer);
  }
  @Test
  public void go() throws Exception {
    controller.go(new Calculator());
    assertEquals(stringBuffer.toString(), "Enter a number: \n"
            + "Enter another number: \n"
            + "The answer is: 14");
  }
}
We also talked about the importance of using a general interface whenever you can I.E. using List<Card> instead of ArrayList<Card>. Luckily I designed my second assignment properly, so I won't have to do a big load of refactoring.
Next class we're probably going over more about Views in MVC.