Need advice on proper class design - java

I am supposed to write a simple Cinema Booking System, which allows a customer to make reservations for movies.
The Cinema consists or different theatres, with different amount of seats, price and movie showtimes.
The user should be able to input his name and other credentials and then make reservations for 1 or more movies and seats.
When he is finished booking, the system should output a receipt, listing his name, the movie(s) the showtime(s) and reservation number.
I have tried to follow the OOP-principles as best to my current capabilities.
The classes I've set up would be the following:
CinemaBooking -> entrypoint into programm
Room -> receives its seating size via [row] [col]
Movie -> has movietitle, shwotime, the room and a price.
Customer -> shoud store any user info like name , email and phone and generate
booking number
I am a bit unsure on where to put the user-i/o in this case: Shoud it remain within CinemaBooking, or should i generate a seperate class which only does the I/O?
Or should I just move the whole I/O stuff to another class (e.g. the Customer Class)?

There are many advises to be given, I'll give only most important.
First, the main idea of OOP was to suit real world, so it's better to make your classes as close to real objects as possible.
Create class Booking which will be just equivalent of a ticket, not an entry point for a program. I.e. it will contain information about user, theatre, seat and cost.
Create class Theatre which will contain number of seats (not rows x cols - some seats may be reserved, some may be broken, and some theatres just haven't squared structure). Alternatively, since one Theatre can have several rooms, you can create class Room, which will have property "seats", and then add Rooms to Theatre.
Also create class Movie. Movies and Theates/Rooms will ref each other: Movie will contain list of Theatres it is showed in, and Theatre will have list of Movies it shows.
Then create class Seance, which will contain time and movie.
Create class Customer only in case you will work with this customer later and want to save his attributes (name, history of bookings, etc.). Otherwise it makes no sense to create one more class.
This is your model. Classes may very a bit, but if you got core idea, this won't be a problem.
Second, create class BookingSystem which will summarize functionality of all previous classes. It will be an implementation of Facade design pattern, and it really simplifies access to your booking subsystem.
Third, create separate class for I/O work. Never put I/O work to the model classes. Imagine, that your cinema booking system will be the part of another system with it's own I/O - you will need to redesign all your code to receive data from higher layers. So, just make separate class for user's input and program's output.
And this will be your view.
Finally, create main program class. You can give it same name the program have itself of something like that. This one will just control program flow from view to models and back. So, this part is called controller, and overall idea is known as Model-View-Controller pattern.

Whenever I make class, it has following in it:-
All instance variables set to private.
Implement getters and setters.
Implement toString() method.
If you are using Eclipse then it will help you to implement these methods automatically. Just write instance variables, right click in editor -> Source -> Generate getters and setters.

Write toString() methods on all the classes. Worry about the I/O later. Get the relationships right first. I/O is the least of your worries.

Actually, ticket will not contain info about user theatre seat or cost. It will contain references to other objects: User, Theater, Seat Cost.
You will need o0ne "manager" type class that will hold the rest of the program: BookingApp which has a main() could be it. I agree don't worry so much about interface for now - but DO NOT print to the terminal from Domain classes. Use toString() to test the object content, but the main() method should call getters on the other classes and create the output.
Very bad idea and form to have domain classes writing directly to the UI.
So, you have Theatre, User, Seat, Ticket, Price. Consider dependencies. Seat is tied to theatre and price is based on theatre and seat, I assume.
Start with the Things, and draw lines between them to show how they will communicate or reference each other. For example, given a User, find all their tickets - from ticket find seat and from seat find theatre.
Then add the attributes (private as JavaGeek said).
Start small. Maybe just Theatres and Seats. Get that to work then add the next class. Add to your design incrementally and iteratively. DO NOT try and write and compile the whole thing at once.
I suggest Peter Coad's Java Design book ( very cheap and very good) as a good intro to java design.

Related

How to decide methods in class

I am new to Object Oriented Programming. I am developing a software for a Grocery Store. The Grocery Store has Customers, Customers has Address and Subscriptions. All these are different classes in the application.
I am little confused, that in which class should I create which method and how I should decide this.
Like
viewSubscription() should be a part of Subscription class or Customer class.
modifyCustomer() should be a part of Customer class or Store class.
Methods are behavior, variables are state.
What can a subscription? from what is a suscription made?
A Suscription cant view itself, who will view a subscription? a customer?
A suscription should be a class indeed, but a POJO, its a collection of states. And customers can see those states.
One of the ideas of object oriented programming is to group things together that make sense. In your example, since they are dealing with information related to the Customer, I would probably place both methods in the Customer class.
OOP makes it easy to break down complex problems. You might want to sit down and do a schema of the relations between your classes and what data your classes will contain. It will become obvious where which method should go.
Why should view subscription should a member of Subscription?
Always ask your self this simple question: view subscriptions of what? On what do you want to do the action.
I bet you want to view the subscription of a Customer! Make viewSubscription a method of Customer! customer1.viewSubscription()
Check out UML and OCL. They will help you to model your ideas.
Just an overview: An object represents a real life entity lets say for example a car, A car has some properties like it has wheels,a steering,a gearbox and much more, the same way it has some behaviors like it moves forward, steers left, steers right and it stops.
All the things mentioned above related to the car when brought down to an Object oriented programming approach will look like, We make a class Car and the properties(wheels,a steering,a gearbox etc) are defined as variables inside that class and the behaviors(moves forward, steers left, steers right) are defined as functions in that class.There's no hard and fast rule relating OOP you just have to make it feel logically as Real Life as possible for instance in your case the Subscription Class has all the information related to the subscription and the Customer has a subscription so the viewSubscription()method should come inside Customer Class as a Private field because it should fetch and display the subscription information related to a particular customer. modifyCustomer() as it involves modifying the data fields of the Customer class so this too will come inside the customer class as all the modification of the field values should probably be done inside the class containing the fields.

Java E-Shop project

So I have an exercise about creating a functional e-shop with a minimal CMD UI. I have certain instructions and rules to follow while creating this and that's what makes it so difficult for me.
So firstly I have to create a class ierarchy, at the top of which stands the general Product.class and then below that the sub-classes Motherboard, CPU, GPU etc. Each of these sub classes contain their respective constructors. However, in the description of my exercise it isn't stated which items are going to be avalaible for immediate sale or should be ordered. Thus, I think that I'm supposed to choose these randomly meaning that I will have to create each and every one of these 'objects' by calling their constructors, like Motherboard mb1 = new Motherboard(motherboard info). Is there another way of implementing this? Because it seems like it's not the best way.
Now for my problem, say I have the required objects created and through the UI and consecutive questions the user will choose what product to buy, how am I going to 'transfer' this chosen object to my Sale.class so I initiate the sale and go on with the program?( The sale class has to print the item's info which is stored in its object and then reduce the items quantity from the shop's reserve)
Thanks in advance!
Your sale class should have a reference to the listed items. This probably should be a List or a Set.

How can I design this concept in a object oriented manner?

I am having a bit of issues with design. Maybe I am thinking about this all wrong, but it seems that what I am designing only works well in a procedural manner.
The Game
I am working on a game, this game has about 10-20 players inside of it, and consists of 3 rounds. When players start up the game, the server loads their data from a database, stores it in a java class, and sends data that is requested to the client. Lets call this Player.java. This class is persistent in between the rounds of the game.
Every player in the game also has a role. This role changes in-between each round and I need this role to be linked with Player.java in some way. Right now I have 3 roles: Hunter, Seeker, and Spectator. Each role has the same basic things: onDeath(), onRespawn(), onKill(KillEvent event). I also need to be able to easily check what role a player is. (For example linking the roles with a enum).
The Problem
The problem I am running into now is how do I implement this in a OOP way? Originally, I had each role as a class that implements Role.java, and every time a role is created, it takes a Player in the constructor. This is all fine and dandy until I start changing people's roles in the middle of the rounds and after the end of each round. It seems like bad practice to me if I am consistently setting the players role to a new object.
Summary
To sum this up (since I am terrible at describing things), it seems like all of this would work perfectly in a procedural manner, but I can't figure out for the life of me a good way to implement this concept using OOP. The way I have it implemented now, each Player has a enum stating what role they are, and to change that role I simply change the enum in Player. With that being said though, once I get to the game logic, I end up with a TON of nested if statements, something that I feel could be greatly reduced with some polymorphism.
So to end with a question, what would be a good plan of attack to implement this (or a slightly modified version of this system) in a object oriented way without having to consistently create new objects that take in data from old objects? (I don't have a ton of experience with OOP, but to me this just seems like a bad idea)
I think I would go for this solution:
Make Player an Interface
Create a Proxy-Class for it (a class that has only one property, which is of type Player, and redirects all methods to this object). Lets call it ConcretePlayer
Add a setRole method, taking a Role to ConcretePlayer.
Make Role implement Player
Create Subclasses of Role like you did, each takes a ConcretePlayer in their constructor.
Store the stats that are shared among all Roles in the ConcretePlayer
Externally use Player or ConcretePlayer to access everything.
It's not fleshed out perfectly, but I think you get the idea. You may find that Role and Player shouldn't share the same interface, or that you want to create an own interface for the callbacks, but that depends on the rest of your code and usecases.

Designing a program with statistics

I am about to start my newest project, it is basicly an application that gets some data from a database and then display that data a graph!
now even though that this may seem simple it is important to me that this is done in a very correct way when it comes to object orientated programming.
Now my idea was the following:
I wanted to create the following four classes:
Adapter:
The class that connects the application to the database and recives the data
CallQueue:
This is an object that differences depending on what type of data is recived from the database and what type of data you wish to show on your graph. An example of this would be Cheese and fruits. both of them are food but they are very different types of food.
Statistics
This would be a tool class used to calculate the information recived from the database (for example changeing it to percentage instead of raw data)
Graph
This would be the class that gets the information from the statistic class and turns the numbers into a graph
GUI
This is ofcourse the GUI class where i will post the graph on!
Now i want to make the project as object orientated as possible. But my problem is that the information from the database is not always the same. For example if get the data from a day to day basis it will be different than from month to month. This means that the information is always going to change depending on what the user need.
How would i make this program object orientated ? and what type of connections should my classes have to eachother to make it most accessible. Do i have to create subclasses in order to simplify it?
should i add all information from the datbase directly into the CallQueue Class or should that object be created later on?
Update - Elaboration
The name callQueue is not a streaming implementation it is marely an object that should contain values of the data recived from the database (note that this is still in the idea phase and nothing is implemented). The idea is that a user opens the program and then chooses a day from and then a day to for instance: 04/11/2012 to 10/11/2012. The reason the objects value changes is when the day changes for instance to the following: 04/11/2012 - 04/12/2012 then a new graph will be created new information from the database will be calculated ect ect.
One thing that i am confused about aswell is the following:
When you have an object that is created from the database (adapater Note this could be optimized if you guys have a better idea) then how would you calculate statistics from that? would it be better that the statistic class called the adapter for data then worked with the data and then created the objects contain the calculated data?
Then the Graph class would need to get the objects data and insert into the graph.
From experience designing large systems and even smaller, the best approach is to think in terms of components rather than classes. This will allow you to break down your problems into smaller (and mostly independent) pieces.
So for example, you will have a component which sole responsibility will be to bring the data to your application for processing. That component will need to be able to deal with the multiple data sources, etc... That then becomes a sub-system that you can design independently from the rest of the application and deals with a specific problem, smaller than the whole.
If the sub-problems are still larger than they should, keep breaking them down into sub-compoennts, until the implementation of the components becomes almost trivial. At that point, you can start bringing in the notion of classes because you have enough visibility on the protagonists in your system.
In short, I put a lot of emphasis on separation of concerns. By isolating sub-problems into sub-components, you also isolate the solutions which makes it easier to correct your design mistakes or replace implementations without impacting the entire system.
Just my two cents...

OO vs Simplicity when it comes to user interaction

As a project over summer while I have some downtime from Uni I am going to build a monopoly game. This question is more about the general idea of the problem however, rather than the specific task I'm trying to carry out.
I decided to build this with a bottom up approach, creating just movement around a forty space board and then moving on to interaction with spaces. I realised that I was quite unsure of the best way of proceeding with this and I am torn between two design ideas:
Giving every space its own object, all sub-classes of a Space object so the interaction can be defined by the space object itself. I could do this by implementing different land() methods for each type of space.
Only giving the Properties and Utilities (as each property has unique features) objects and creating methods for dealing with the buying/renting etc in the main class of the program (or Board as I'm calling it). Spaces like go and super tax could be implemented by a small set of conditionals checking to see if player is on a special space.
Option 1 is obviously the OO (and I feel the correct) way of doing things but I'd like to only have to handle user interaction from the programs main class. In other words, I don't want the space objects to be interacting with the player.
Why? Errr. A lot of the coding I've done thus far has had this simplicity but I'm not sure if this is a pipe dream or not for larger projects. Should I really be handling user interaction in an entirely separate class?
As you can see I am quite confused about this situation. Is there some way round this? And, does anyone have any advice on practical OO design that could help in general?
EDIT: Just like to note that I feel I lost a little focus on this question. I am interested in the general methodology of combining OO and any external action(command line, networking, GUI, file management etc) really.
In the end, it is up to you. That is the beauty of OO, in that it is subject to interpretation. There are some patterns that should usually be adhered to, but in general it is your decision how to approach it.
However, you should carefully consider what each actor in the system should know about the rest of it. Should a property really know about the player, his account balance, and the other players? Probably not. A property should know what it costs, how much its rent is, etc.
On the other hand, should the main playing thread be concerned about trivial matters such as paying rent? Probably not. Its main concern should be the state of the game itself, such as dice rolling, whether each player wants to trade or buy or unmortgage/mortgage, things like that.
Think for a moment about the action of landing on a square. Once landed, the player has 3 options:
Buy the property
Ignore the property
Pay rent
Now, which actor in the system knows all the information required to complete that. We have the Game class, which isn't concerned with such tedium. We have the Property, which doesn't really care about the players. But the Player object knows all this information. It keeps a record of what each player owns, and can easily access the proper data.
So, if it were me, I would make a Player.performMove(Die d) method. It has easy access to the accounts. This also allows for the least coupling among classes.
But in the end, it's up to you. I'm sure people have created Monopoly clones in perfect OO, as well as Functional or Procedural languages too. In the end, use what you know and keep refactoring until you're happy with the end design.
I agree option #1 seems better.
As for "user interaction" - it all depends. You could leave some of your code in another class. For example,
// in main class
user.landOn(space);
if (space.containsProperties()) doSomething(); // Option #1 for some user-interaction code
// in User.java
public void landOn(Space s) {
// do some checks
s.land(this);
if (s.containsProperties()) {...} // Option #2
// something else?
}
// in GetMoneySpace.java
#Override
public void land(User u) {
u.awardCash(200);
// Option #3 - no properties so nothing here
}
This is far more OOP-y (and better, in my opinion) than something like
if (space.isCashAwardSpace()) {
user.awardCash(space.getAward());
}
if (user.something()) doSomething(); // Some user-interaction code
I am not entirely sure if I understand it correctly. You have always such choice when designing software. I would personally go for the first choice. One argument is personal experience with small games (Scrabble), which prooved to me that good design matters for smaller projects as well. The point of OOP is that you can think differently about your design and you get some design benefits. For example imagine how hard it will be to add new field, change existing one, reuse behaviour of one field in multiple fields.
Your first approach is the one I'd go for. It encapsulates the behaviour where it's needed. So, you'd have Space subclasses for Utilities, Properties, GotoJail, FreeParking - basically all the different cateogires of spaces. What groups a category is it's common behaviour.
Your properties spaces may themselves have a group object as a member, e.g. to group all the dark blue properties together.
As to interaction with the user, you pass a Board (or better a GameController) instance to each space, so it knows which Game it is part of and can influence the game. The Space can then invoke specific actions on the board, such as, moving a piece, asking the user a question etc. The main point is that there is separation - the user interaction is not happening inside each Space - but the space is allowed to request that some interaction happens, or that a piece is moved. It's up to your GameController to actually do the interaction or move pieces etc. This separation makes it easy to test, and also provide alternative implementations as the need may arise (E.g. different game rules in different editions/countries?)
Go with the first design. You'd have a Property class, and subclass the special properties, overriding the default behavior.
As far as interaction, you could have a Token class, and move an instance of that around the board. You have to give the user some options, but yes, from the responses, you should be calling methods on objects, not putting complex logic in the user events.
Sample classes:
Property
name
price
baseRent
houseCount
hotelCount
mortgaged
getCurrentRent()
RailRoad extends Property
Utility extends Property
Board
properties
User
token
playerName
currentProperty
ownedProperties
buyProperty()
payRentOnProperty()
mortgageProperty()
move()
Option 2 doesn't make much sense, or at least it's not as clear to me as option 1. With option 1 you don't need to handle user interaction inside your space object. You could have in your main class or a separate class dedicated to handle user interaction:
public void move(Player p, int spaces){
Space landingSpace = board.getLandingSpace(p,spaces);
landingSpace.land(p); //apply your logic here
}
As you can see, the Space class is responsible for checking the Player p that intends to land on that space. It applies any custom logic, checks if it has enough money, if it's something that the player owns, etc. Each subclass of Space will have its own set of rules, as you described in option 1.
Part of the point of object-oriented design is to simplify the representation of the problem within the solution space (i.e., modeling the system in the computer). In this case, consider the relationships between objects. Is there enough functionality in a Space to warrant abstracting that into a class, or does it make more sense for there to be discrete Property and Utility classes unrelated to Space because of the unique features of both? Is a Property a special kind of Space, or merely a field within Space? These are the kinds of problems you probably will need to grapple with in designing the game.
As far as interaction, it's generally bad news for a design when you have a 'god class' that does all the work and merely asks the other classes for information. There are plenty of ways to fall into this trap; one way to determine whether you are dealing with a god class is to look for a class name including Manager or System. Thus, it's probably not the best idea to have some sort of "game manager" that asks all the other objects for data, makes all the changes, and keeps track of everything. Eliminate these as much as possible.
God classes violate the concept of encapsulation, which involves more than data hiding (though that's certainly a big part of it). Good encapsulation means that related methods and data are part of a single object. For example, a Property doesn't need to make requests of its owner, so a field containing a reference to the Player could violate encapsulation. Some of these encapsulation violations aren't obvious at all, and can be hard to spot. When designing the object, try to determine the smallest amount of information about the object that needs to be shared with external objects. Trim out anything unnecessary.
You can obviously go about this in a lot of ways, but my design would be something like this (iteration could certainly prove it wrong):
Space class that contains basic data and methods that are common to all spaces (such as their position on the board, occupied or not, etc.).
Subclasses moving from most common (Property and Utility) to most unique (Go, Jail, FreeParking, and so on; probably singletons) with fields and methods related to each.
Player class to contain player information.
GameState class that is concerned with game state; whose turn it is, how many houses are left in the bank, and so on.
Good luck with the game and your continued studies.
Naturally, Google is your friend, but here's a sampling of things I would recommend reading:
ATM simulation (this idea is
also discussed in Rebecca
Wirfs-Brock's book below)
Object-Oriented Design Heuristics - Arthur Riel
How Designs Differ (PDF), Designing Object-Oriented Software - Rebecca Wirfs-Brock

Categories