Lab#SE02-1: Movie/Review, Model

Java SE Lab 02 part 1

javase
lab
composition
model
Java SE Lab 02, part 1 work on the Model
Author

vcalvache

Published

Monday, October 2, 2023

Modified

Friday, March 3, 2023

1 Goal

The goal of this project consist on creating different Java classes to define the Model of a project based on Movie Reviews.


2 Tasks

  • Create a Java SE Project with Maven.

  • Add dependencies: + Junit + Java Faker + Lombok

  • Create the following Java classes:

    • Movie: represents a movie that is going to be reviewed. Should have this attributes:
      • title
      • reviews
      • Critic
    • Critic: is the one who will write reviews. Their attributes:
      • name
      • Review
    • Review: is written by the critic and belongs to the movie. Theis attributes:
      • Movie
      • Critic
      • rating
      • comment
  • Create unitary tests wit Junit.

  • Add new feature once all the test are passed.


3 Adding dependencies

After creating the Maven project, the first step consist in adding the dependencies to the pom.xml project.

The desires dependencies can be found on the Maven Repository link:

On the code below, Junit, Lombok and Java Faker has been added.

pom.xml
  <dependencies>
    <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.26</version>
      <scope>provided</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
      <version>5.9.2</version>
      <scope>test</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.github.javafaker/javafaker -->
    <dependency>
      <groupId>com.github.javafaker</groupId>
      <artifactId>javafaker</artifactId>
      <version>1.0.2</version>
    </dependency>

  </dependencies>

4 First UML

As a first approach to start working on, the UML is based on the following rules:

  • The Movie Class is designed where an object movie can has different reviews.
  • Critic create objects for the Review class of a movie object.
  • The Review class depends on the Critic class and belongs to a movie object.

On this design we can see that the Movie class will have a multiplicity with the Critic class (since a movie can be reviewed by different critics). Also, the Critic class will has a multiplicity relationship wit the review class because a critic object can has multiple reviews of different movies.

classDiagram
  class Movie {
    -title: String
    -reviews: ArrayList Review
  }
  class Critic {
    -name: String
  }
  class Review {
    -movie: Movie
    -critic: Critic
    -rating: int
    -comment: String
  }
  Movie *-- Review
  Review o-- Critic


5 Creating classes

Proceeding with the tasks given, now it’s time to create the classes as per the UML designed.

The first class to be created is the Movie class. Lombok is used to create two constructors, one will al arguments, and another with no arguments (will allow to create empty objects). A third constructor is created. This constructor only needs a String whit the movie name.

Movie.java
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Movie {
    // first approach for Movie class
    private String movieName;
    private ArrayList<Review> reviews;
    private Critic critic;

    public Movie(String movieName){
        this.movieName = movieName;
    }
}

Critic class is the same as the Movie class. Lombok creates two constructors and a third one that will allow creating Critic objects only with the criticName.

Critic.java
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Critic {
    //first approach for Critic class
    private String criticName;
    private Review review;

    public Critic(String criticName){
        this.criticName = criticName;
    }
}

The Review class works only with two constructors, with all the arguments or without any. This way Reviews can only be created if i have all the parameters or empty, so it can be setted later in case that all the parameters doesn’t exist yet.

Review.java
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Review {
    // First approach for Review class
    private Movie movie;
    private Critic critic;
    private int rating;
    private String comment;
}

6 First tests

With the classes already created it’s time to run the first test.

This first test consists on manually creating a Critic object, sets the name, prints it on screen and using assertEquals and assertNotEquals to compare both results, true and false.

CriticTest.java
public class CriticTest {

    @Test
    public void createCriticObjectTest(){
      // Manually creating a Critic object.
      Critic critic = new Critic();
      critic.setCriticName("Victor");
      System.out.println(critic.getCriticName());
      // assertEquals and assertNotEquals testing
      assertEquals("Victor", critic.getCriticName());
      assertNotEquals("Paco", critic.getCriticName());
    }
}

This second test uses the Faker library. First, a Movie object is created passing the movie name as a parameter when creating. Then, a faker object is created and will be used so declare a String with fake data. Then, an assertEquals and assertNotEquals compares are called.

MovieTest.java
public class MovieTests {

    @Test
    public void createMovieObjectTest(){
      // Manually creating a movie object.
      Movie alien = new Movie("Alien");
      Faker faker = new Faker();
      String name = faker.twinPeaks().character();
      // assertEquals and assertNotEquals testing
      assertEquals("Alien", alien.getMovieName());
      assertNotEquals("Alien", name);
    }
}

The ReviewTest class consist on manually creating a Movie object, a Critic object. When creating a Review object, all parameters are given on the creation of the object. Again, assertEquals and assertNotEquals compares the expected output with the actual output.

ReviewTest.java
public class ReviewTest {

    @Test
    public void createReviewObjectTest(){
        //Creating a review and set comment manually.
        Movie alien = new Movie("Alien");
        Critic victor = new Critic("Victor");
        Review alienReview = new Review(alien, victor, 5, "Must see");
        // assertEquals and assertNotEquals testing
        assertEquals("Must see", alienReview.getComment());
        assertNotEquals("Predator", alienReview.getMovie().getMovieName());
    }
}

This last test is made on the AppTest clases, to test the workflow of our program. First, empty objects are created. The next block of code fakes parameters. The third block of code sets all the faked parameters created. Note that on the setting parameters for the movie object, first we add a Review object to an ArrayList, and then is setted as a parameter.

And lastly, the expected output and the actual output is tested with assertEquals and assertNotEquals testing.

AppTest.java
public class AppTest
{
   @Test
    public void creatingMoviesAndReviewsTest(){
      // creating empty objects
       Faker faker = new Faker();
       Random random = new Random();
       Critic boyero = new Critic();
       Movie alien = new Movie();
       Review alienReview = new Review();
       ArrayList<Review> allAlienReviews = new ArrayList<>();

       // faking params
       String criticName= faker.twinPeaks().character();
       String textOfReview = faker.twinPeaks().quote();
       String movieName = faker.twinPeaks().location();
       int rating = random.nextInt(1, 5);

       //setting critic params
       boyero.setCriticName(criticName);
       boyero.setReview(alienReview);

       //setting review params
       alienReview.setCritic(boyedo);
       alienReview.setComment(textOfReview);
       alienReview.setRating(rating);
       alienReview.setMovie(alien);

       //setting movie params
       allAlienReviews.add(alienReview);
       alien.setCritic(boyero);
       alien.setMovieName(movieName);
       alien.setReviews(allAlienReviews);

       // testing equals and not equals.
       assertEquals(movieName, alien.getMovieName());
       assertNotEquals("Gladiator", alien.getMovieName());
       System.out.println(textOfReview);

       assertEquals(textOfReview, alien.getReviews().get(0).getComment());
       assertNotEquals("text", alien.getReviews().get(0).getComment());
   }
}

7 Expanding UML

Now that we have our core classes ready and tested, it’s time to add new features. This will change the first UML that worked as some sort of a draft.

classDiagram
  class Movie {
    - title: String
    - reviews: ArrayList Review
    - awards: ArrayList Awards
  }

  class Review {
    - movie: Movie
    - critic: Critic
    - rating: int
    - comment: String
  }

  class Person{
    - name: String
  }

  class Director extends Person{
    - movies: ArrayList Movie
  }

  class Critic extends Person{
    - reviews: ArrayList Review
  }

  class Awards{
    - oscars: Set Oscar
  }

  class Oscar extends Awards{
    - Boolean won
  }
  Movie *-- Review : Composition
  Review o-- Critic extends Person : Aggregation
  Movie *-- Awards : Composition
  Awards <|-- Oscar extends Awards : Inheritance
  Person <|-- Director extends Person : Inheritance
  Person <|-- Critic extends Person : Inheritance