Object Oriented Design

Second day of OOD we dive right in to books and citations. Basically we have books and two ways to cite them: MLA and APA. What happens when we want to add a new citation for websites. In our original system we just have to add one case. The racket code to do this properly looks like this:

;; new-article: String String String Number Number Number -> Publication
;; To construct a new article.
(define (new-article title author journal volume issue year)
  (lambda (style)
    (cond
      [(string=? style "apa")
       (format "~a (~a). ~a. ~a, ~a(~a)."
               author year title journal volume issue)]
      [(string=? style "mla")
       (format "~a. \"~a.\" ~a ~a.~a (~a)."
               author title journal volume issue year)])))

;; Examples:
(define turing
        (new-article "Computing machinery and intelligence"
                     "A. M. Turing" "Mind" 59 236 1950))

(check-expect (turing "apa") (cite-apa turing))
(check-expect (turing "mla") (cite-mla turing))

;; new-webpage: String String String -> Publication
;; To construct a new web page.
(define (new-webpage title url retrieved)
  (lambda (style)
    (cond
      [(string=? style "apa")
       (format "~a. Retrieved ~a, from ~a."
               title retrieved url)]
      [(string=? style "mla")
       (format "\"~a.\" Web. ~a <~a>."
               title retrieved url)])))

;; Examples:
(define cs3500
        (new-webpage "CS3500: Object-Oriented Design"
                     "http://www.ccs.neu.edu/course/cs3500/"
                     "August 11, 2014"))

(check-expect (cs3500 "apa") (cite-apa cs3500))
(check-expect (cs3500 "mla") (cite-mla cs3500))

Racket can do this, however, there’s no way to enforce it. The advantage of Java is that it can force us to give structure. To do this, we use an interface:

/**
 * Specifies operations for formatting citations from bibliographic data.
 */
public interface Publication {
  /**
   * Formats a citation in APA style.
   *
   * @return the formatted citation
   */
  String citeApa();

  /**
   * Formats a citation in MLA style.
   *
   * @return the formatted citation
   */
  String citeMla();
}

From there we can have a class that represents each kind of publication (book, article, webpage). In racket the operation of citation takes and churns something else, in Java the operation is encapsulated in the object. Now we add the following properties:

/**
 * Created by jea on 1/13/17.
 */
/*
 * This class represents a specific kind of publication
 * A book has an author, title, publisher, location, and year
 */
public class Book implements Publication{
    private final String author, title, publisher, location;
    private final int year;

  /** Constructs a {@code Book} object.
   *
   * @param title     the title of the book
   * @param author    the author of the book
   * @param publisher the publisher of the book
   * @param location  the location of the publisher
   * @param year      the year of publication
   */
    public Book(String author, String title, String publisher, String location, int year) {
        this.author = author;
        this.title = title;
        this.publisher = publisher;
        this.location = location;
        this.year = year;
    }

    /**
     * Formats a citation in APA style.
     *
     * @return the formatted citation
     */
    @Override
    public String citeApa() {
        return null;
    }

    /**
     * Formats a citation in MLA style.
     *
     * @return the formatted citation
     */
    @Override
    public String citeMla() {
        return null;
    }
}

Now we implement the methods:

/**
     * Formats a citation in APA style.
     *
     * @return the formatted citation
     */
    @Override
    public String citeApa() {
      return String.format("%s (%s). %s. %s: %s",
              this.author,
              this.year,
              this.title,
              this.location,
              this.publisher);
    }
    /**
     * Formats a citation in MLA style.
     *
     * @return the formatted citation
     */
    @Override
    public String citeMla() {
      return author + ". " + title + ". " + location + ": " + publisher + ", " + year + ".";
    }

And now we add testing. In this class, we’re going to be using JUnit, which is a solid testing library. This is what that looks like:

/**
 * Created by jea on 1/13/17.
 */
public class BookTest {
  Publication rushdie = new Book("Midnight's Children", "Salman Rushdie",
          "Jonathan Cape", "London", 1980);

  @Test
  public void testCiteApa() {
    assertEquals("Salman Rushdie (1980). Midnight's Children. "
                    + "London: Jonathan Cape.",
            rushdie.citeApa());
  }

  @Test
  public void testCiteMla() {
    assertEquals("Salman Rushdie. Midnight's Children. London: "
                    + "Jonathan Cape, 1980.",
            rushdie.citeMla());
  }

}

Now we’re moving to obsevers and adhereing to Java standards about basic observers and operations like comparisons, add, subtract, etc. And that’s class.

The assignment up now, pretty easy. Already did the first half. The second half is making a custom formatter. I want to try out some Java 8 streams, so here’s a taste:

char[] c = s.toCharArray();
IntStream.range(0, s.length() - 1)
        .filter(i -> c[i] == '%')
        .mapToObj(i -> c[i+1])
        .forEach(System.out::println);