oop - How can I link an object to another object in Java? - Stack Overflow
I am building a movie theatre application in Java and need some help with linking objects. I have created three classes: Person, Movie, and Extra.
Currently, I have a scenario where a Person (like John or Sam) can add a Movie (like "Fight Club") to their list of movies. I want to ensure that each person can choose different extras for the same movie. However, when I add an extra (e.g., "Popcorn") to a movie, it gets added for all people watching that movie, rather than just the individual person.
Here's an example:
John wants to watch "Fight Club" and add the extra "Popcorn." Sam wants to watch the same movie but prefers the extra "Drink." The problem is that when I add "Popcorn" to the movie, it ends up being added to the movie for both John and Sam, instead of just for John.
Here’s my code:
Person:
public class Person {
private String name;
private int attendeesCount;
private List<Movie> movies;
public Person(String name, int attendeesCount) {
this.name = name;
this.attendeesCount = attendeesCount;
this.movies = new ArrayList<>();
}
public void addMovie(Movie movie) {
movies.add(movie);
}
}
Movie:
public class Movie {
private String title, description;
private int price, duration;
private List<Extra> extras = new ArrayList<>();
private Movie(String title, int price, String description, int duration) {
this.title = title;
this.price = price;
this.description = description;
this.duration = duration;
}
public void addExtra(Extra extra) {
this.extras.add(extra);
}
}
Extra:
public class Extra {
private String name;
private int price;
public Extra(String name, int price) {
this.name = name;
this.price= price;
}
}
Main:
public class TestTheatre {
public static void main(String[] args) {
Movie fightClub = new Movie("Fight Club", 1000, null, 90);
Movie theMatrix = new Movie("The Matrix", 2000, null, 80);
Extra popcorn = new Extra("Popcorn", 500);
Extra drink = new Extra("Drink", 400);
fightClub.addExtra(popcorn); // Here is where I am adding the extra to the movie
Person john = new Person("John", 2);
Person sam = new Person("Sam", 3);
john.addMovie(fightClub);
john.addMovie(theMatrix);
sam.addMovie(fightClub);
}
}
I understand that the issue occurs because I’m adding extras to the movie globally, which applies the extras to all persons who watch that movie however, I just can't work out how I can solve this. Any help would be greatly appreciated.
I am building a movie theatre application in Java and need some help with linking objects. I have created three classes: Person, Movie, and Extra.
Currently, I have a scenario where a Person (like John or Sam) can add a Movie (like "Fight Club") to their list of movies. I want to ensure that each person can choose different extras for the same movie. However, when I add an extra (e.g., "Popcorn") to a movie, it gets added for all people watching that movie, rather than just the individual person.
Here's an example:
John wants to watch "Fight Club" and add the extra "Popcorn." Sam wants to watch the same movie but prefers the extra "Drink." The problem is that when I add "Popcorn" to the movie, it ends up being added to the movie for both John and Sam, instead of just for John.
Here’s my code:
Person:
public class Person {
private String name;
private int attendeesCount;
private List<Movie> movies;
public Person(String name, int attendeesCount) {
this.name = name;
this.attendeesCount = attendeesCount;
this.movies = new ArrayList<>();
}
public void addMovie(Movie movie) {
movies.add(movie);
}
}
Movie:
public class Movie {
private String title, description;
private int price, duration;
private List<Extra> extras = new ArrayList<>();
private Movie(String title, int price, String description, int duration) {
this.title = title;
this.price = price;
this.description = description;
this.duration = duration;
}
public void addExtra(Extra extra) {
this.extras.add(extra);
}
}
Extra:
public class Extra {
private String name;
private int price;
public Extra(String name, int price) {
this.name = name;
this.price= price;
}
}
Main:
public class TestTheatre {
public static void main(String[] args) {
Movie fightClub = new Movie("Fight Club", 1000, null, 90);
Movie theMatrix = new Movie("The Matrix", 2000, null, 80);
Extra popcorn = new Extra("Popcorn", 500);
Extra drink = new Extra("Drink", 400);
fightClub.addExtra(popcorn); // Here is where I am adding the extra to the movie
Person john = new Person("John", 2);
Person sam = new Person("Sam", 3);
john.addMovie(fightClub);
john.addMovie(theMatrix);
sam.addMovie(fightClub);
}
}
I understand that the issue occurs because I’m adding extras to the movie globally, which applies the extras to all persons who watch that movie however, I just can't work out how I can solve this. Any help would be greatly appreciated.
Share Improve this question edited yesterday Progman 19.4k7 gold badges51 silver badges78 bronze badges asked yesterday John BowlerJohn Bowler 182 bronze badges 2 |3 Answers
Reset to default 7As you already have identified, you shouldn't add the extras to the movies. The extras are not part of the movies so delete the private List<Extra> extras
field from the Movie
class. Same goes with the list of movies in the Person
class. The movies are not part of a person.
Instead, depending on what you want to do, create a new Reservation
or Booking
class, which references a Person
and a Movie
. This class can have your List<Extra>
field for the extras the person is having when watching the movie.
Tip: Thoughtful naming can be critical in discerning a proper design for your software.
Let's make Extras more specific: Food (although the stuff at theaters barely qualifies).
If the menu of Food
items and their price are known at compile-time, then make the class an enum.
package work.basil.example.collections.theater;
enum Food
{
SODA ( 1 ),
BEER ( 4 ),
POPCORN ( 2 ),
JUJUBE ( 1 );
final int price;
Food ( final int thePrice )
{
this.price = thePrice;
}
}
And “Person” should really be Customer
. But you are not actually tracking the customer. You seem to be tracking only the purchases made by any customer, pairing each admission to a movie with optional food items. This could be realistic, I suppose, especially for online orders made ahead of time. (Stating the business requirements clearly and specifically is another crucial element of software design. Your requirements statement is vague, lacking detail.)
So your apparent requirements means we have a Purchase
object needing a reference to a Movie
object, as well as a reference to a Collection
of zero or more Food
objects.
So we need a Movie
class.
If the primary purpose of a class is to transparently communicate shallowly-immutable data, make it a record. This class merely represents each movie being shown. This is not the place to track purchases.
Regarding the duration of the movie, we have a class for that: Duration
. We can use that as the type of our member field rather than your choice of int
.
public record Movie( String title , int price , String description , Duration duration ) { }
Our Theater
object comes with a list of the currently-playing movies.
The theater sells admission tickets and food items, not the movie. So we have maintain a collection of Purchase
objects here.
public class Theater
{
final List < Movie > movies;
final Collection < Purchase > purchases = new ArrayList <> ( );
public Theater ( final List < Movie > theMovies )
{
this.movies = theMovies;
}
}
Back to our Purchase
class. We can track each purchase with a UUID. And we need the movie along with the food items being purchased.
package work.basil.example.collections.theater;
import java.util.Collection;
import java.util.UUID;
public record Purchase
(
UUID id ,
Movie movie ,
Collection < Food > foodItems
)
{ }
And an app class to pull it all together.
public class App
{
public static void main ( String[] args )
{
App app = new App ( );
app.demo ( );
}
private void demo ( )
{
Theater theater =
new Theater (
List.of (
new Movie ( "Fight Club" , 5 , "Brad Pitt" , Duration.ofMinutes ( 92 ) ) ,
new Movie ( "A River Runs Through It" , 4 , "Brad Pitt & Robert Redford" , Duration.ofMinutes ( 101 ) ) ,
new Movie ( "Thelma & Louise" , 7 , "Brad Pitt, Susan Sarandon, and Geena Davis" , Duration.ofMinutes ( 87 ) )
)
);
theater.purchases.add (
new Purchase (
UUID.randomUUID ( ) ,
theater.movies.get ( 0 ) ,
List.of ( Food.POPCORN )
)
);
theater.purchases.add (
new Purchase (
UUID.randomUUID ( ) ,
theater.movies.get ( 0 ) ,
List.of ( Food.SODA )
)
);
}
}
And now we see the solution to your Question, How can I link an object to another object in Java?. When making a purchase, we create a collection (here, a List
) of food items to be passed to the constructor of Purchase
. That list of food choices is associated with a movie by both being fields on the Purchase
class. In turn, each new Purchase
object gets added to a collection of purchases kept somewhere (here, on the Theater
class).
In a real app, we would have a GUI where the user would select the movie being purchased, and select the zero, one, or more food items to go with that movie ticket.
Movie movie = gui.getMovie() ; // Which in turn would have done something like: `theater.movies.get ( 0 )` from a scroll box.
List < Food > foods = gui.getFoods() ; // Which in turn would have done something like: `List.of ( Food.POPCORN )`.
theater.purchases.add (
new Purchase (
UUID.randomUUID ( ) ,
movie ,
foods
)
);
gui.updatePurchaseComplete() ;
To start off on the right foot, we must ask ourselves questions:
1°) what do we have?
a) Theatre
b) Room
c) Movie
d) ServiceExtra
e) Product
f) Customer
2°) “who” has “what”?
a) Theatre has Room
b) Room has Movie, has ServiceExtra
c) ServiceExtra has Product, has Customer
D) Customer has money, we have to take it away!!!
let's create our classes:
class Theatre {
Room rooms[];
}
class Room {
Movie movie;
ServiceExtra;
int seats[]
}
class ServiceExtra {
Product products[];
Map<Customer, List<Product>> extra;
}
class Customer {
int seatNumber;
String name;
}
class Movie {}
class Product {}
This example is not intended to be the final form of your code (missing fields, methods, etc), nor the best strategy to use, I just hope it serves as a starting point.
- 运动类穿戴设备今年迎爆发 繁荣背后的陷阱
- 谷歌收购移动软件商Quickoffice 整合Apps
- windows 10 - Gamemaker Mobile device Inconsistent Drag Speed Across Different Operating Systems (Win7 vs. Win10) - Stack Overflo
- r markdown - Rstudio custom traceback - Stack Overflow
- node.js - Send GET request with pfx file using AXIOS failed - Stack Overflow
- performance testing - How to retrieve the dynamic value from the JMeter - Stack Overflow
- Prisma create: Typescript error in field data - Stack Overflow
- x86 - how does internal functions of kernel resolve after paging? - Stack Overflow
- android - How to setImageCaptureResolutionSelector() in CameraController? - Stack Overflow
- javascript - Unable to create a framebuffer with an RGBA32F texture - Stack Overflow
- java - JAR works in Command Prompt but not in PHP - Stack Overflow
- using Okta principal groups and metadata in Spring Boot with Okta Spring Boot - Stack Overflow
- Power query performance (SOAP connector) very low on migrating from Excel to Power BI Desktop - Stack Overflow
- smartcontracts - FailedCall() with OpenZeppelin meta transactions (ERC2771Forwarder and ERC2771Context) - Stack Overflow
- visual studio code - VSCode support fully integrated IPython terminal - Stack Overflow
- javascript - useState rerenders bindings increment when key added to object but not removed - Stack Overflow
- flutter - Go_Router infinite loop through redirect - Stack Overflow
Person
have anattendeesCount
? I haven't looked through much of the code, but it doesn't make sense to put it there. – ndc85430 Commented yesterday