Online restaurant reservation system (data structures) - java

I have a task to design an online reservation system.
Where a user can enter zip code/ no of people/time of reservation and get a list of restaurants. Assumption (User and restaurant are always in the same city)
Each restaurant can have multiple tables with different number of seats. So, 2 tables that seat 4 people and 4 tables that seat 4 people.
I'm having trouble coming up with the right data structures to use.
My classes are as follows
Restaurant : Contains timeofopening, timeOfClosing, totalNoOfSeatsAvailable
Not sure how i will store table information within the restaurant. It doesn't make sense to have a separate class for the table. All the info i need is howManytables are free and what are their sizes.
Reservation: This maintains the actual reservation and allows to cancel reservation
ReservationSystem :
contains the interface to `List checkAvailability(long time, int people)'
How will this return this list? I initially thought of using a priorityQueue to maintain a queue with max no of seats available. But then i will go through that list to see if the time is correct to even make the reservation and then once a reservation is made,update this queue. One problem is the queue does all duplicates.
My specific questions are:
How do i store the table information within each restaurant.
What is the best way to maintain this list of restaurants so i can give return a list without having to sort this information everytime.
EDIT:
For the question on how to store the table information. My specific concern is
that storing a table class would mean that i'm creating un necessary objects. Here's my reasoning. 5 tables that seat 2 people each with have the exact same objects - i mean there isn't any meaningful information that will be differnet among them. I just need to numbers. no of seats/table.(If i have a table of 4 but 3 peole, I will consider this table taken)
I thought of creating 3 arrays. Lets say table represent 1,2 etc so int[] differentSeatingOnTable; its indexes are tables and values are seats allowed. Next an array of tables with totalNoOfThosetable where indexs are tables and values are total number of such table. Similary for free tables freeTables where index are table and how many of such free table are left.

1. ) If you just store the amount of seats in a restaurant, you're shooting yourself in the foot. Suppose I need to make a reservation for 16 people, and they all must be on the same table (yes, I need a pretty long table). Your system could take my guests to someplace where they'd have to sit in 8 tables for two people each.
You do need a table class. Then your restaurants need to have collections of tables. If you want to know how many seats you have in a restaurant, you just have to iterate through its table collection and count the seats. And if you want to know if you can sit a family in a single table in a restaurant, you just have to check whether it has any table with that amount of seats.
EDIT: there is a more minimalistic way to store seats per restaurant. Use a dictionary, hash table or any other structure that holds keys and associated values. So have the key represent a type of table. The key may be an integer saying how many people the table sits. The value is the amount of tables of that type present in the restaurant. I think this is way better than my original suggestion.
So, for example, a restaurant with such a hash table:
Key | Value
4 | 5
2 | 8
16 | 1
Has five tables with 4 seats each, 8 tables with 2 seats each, and a single long table that sits 16 people.
(Also using a table to store tables is so meta).
2. ) Your reasoning is right for the reservations. If it is doing duplicates, you should post a more especific question showing how you're doing it so we can try and help you locate the bug.

Relational databases make both these requirements easy.
You'll have two tables: RESTAURANT and SITTING (TABLE is a reserved word in SQL) with a one-to-many relationship between them.
A RESTAURANT will have a name, so you can ORDER BY name.
package model;
class Table {
private int id;
private int numSeats;
public Table(int id, int numSeats) {
this.id = id;
this.numSeats = numSeats;
}
public int getId() { return this.id; }
public int getNumSeats() { return this.getNumSeats; }
}
class Restaurant implements Comparable {
private String name;
private List<Table> tables;
public Restaurant(String name) {
this.name = name;
this.tables = new ArrayList<Table>();
}
public void addTable(Table t) { this.tables.add(t); }
public void removeTable(int id) {
for (Table t : this.tables) {
if (t.getId() == id) {
this.tables.remove(t);
break;
}
}
}
public int getCapacity() {
int capacity = 0;
for (Table t : this.tables) {
capacity += t.getNumSeats();
}
return capacity;
}
public int compareTo(Restaurant r) {
return this.name.compareTo(r.name);
}
}

1) well..i think it makes more sense if you created the table class.its easier than trying to cramp it in the restaurant class.and you would find it easier too
2)maintain a primary key field,maybe a composite key,marking out the uniques,this could keep out duplicates
Reccomendations:
Res_Table class
Restaurant class
primary key fields with ORDERING

Related

Using Android & Google App Engine on Android Studio

I'm developing an app with backend and I decided to try using Google App Engine for my backend. Since I'm really new on Google App Engine, I'm little bit confused with the logic.
Basically, I have a couple of model classes to represent my object types. Lets say one of them is User and another is Item. Users have items and an item can belong more than one user. So User X can have 25 items including Item A, and User Y can have totally different 20 items and also the Item A.
Right now my User class looks like this:
#Entity
public class User {
#Id private Long id;
private String name;
private String emailAddress;
private String photoURL;
//All getters and setters...
}
And my Item class is approximately same. One of my questions is, where should I add some kind of list, like a list of Items into User. And which annotation should I use? What will that annotation provide me as a result (a reference, an id or a complete object)?
Another question related to this is, in my endpoint class, how can I get a list of Items that a specific User has (or list of Users that owns a specific Item)?
One last totally unrelated question, should I do anything to make id auto increment or will it be automatic if I won't provide any id while inserting an item?
You can search in the datastore for 2 things: keys and indexed properties.
class Thing {
#Id Long id;
#Index String property;
}
At some point you save some entities
Thing thing1 = new Thing();
thing1.property = "yes";
Thing thing2 = new Thing();
thing2.property = "no";
ofy().save().entities(thing1, thing2).now();
Now you can search for all entities based on their indexed properties. E.g. for all things with property == "yes".
List<Thing> things = ofy().load().type(Thing.class).filter("property", "yes").list();
Would return exactly thing1.
The same works with Lists of properties. And it works with lists of references/keys to other properties.
class User {
#Id Long id;
#Index List<Key<Item>> items;
}
class Item {
#Id
Long id;
}
List<User> searchUsersWithItem(long itemId) {
Key<Item> itemKey = Key.create(Item.class, itemId);
return ofy().load().type(User.class).filter("items", itemKey).list();
}
List<User> searchUsersWithItem(Item item) {
return ofy().load().type(User.class).filter("items", item).list();
}
// just loads all the referenced items in the owner
List<Item> searchItemsWithOwner(User owner) {
return new ArrayList<Item>(ofy().load().<Item>values(owner.items).values());
}
filter works with refs, keys and entitiy instances.
To be found things must be indexed https://cloud.google.com/datastore/docs/concepts/indexes / https://github.com/objectify/objectify/wiki/Queries
What's left for you to decide is how you model your relation. There are multiple ways. A user that owns a set of items which can be owned by set of users is actually a many-to-many relation. You could represent it like
class User { List<Key<Item>> items; }
class Item { }
or
class User { }
class Item { List<Key<User>> owners; }
or
class User { List<Key<Item>> items; }
class Item { List<Key<User>> owners; }
or even
class User { }
class Item { }
class Ownership { Key<Item> item; Key<User> user; }
Each approach has it's ups and downs with respect to data consistency and searchability / performance. In the initial example it's trivial to search for all items of a user since all you have to to is to load that one user and you have the list of items. The other direction requires the query approach.
So with respect to search performance you benefit from having the list of owners in the items as well as the list of items in the user because that way you don't need queries at all. The big downside becomes data consistency. If you fail to update both user and item at the same time you can have items that believe to be owned by a user where the user thinks different.
The last approach, using an explicit "Ownership" entity is essentially the traditional pivot / junction table https://en.wikipedia.org/wiki/Many-to-many_%28data_model%29 that is the result of transforming a many-many relation into 2 one-many relations. Using that would result in easy consistency, but the worst query performance.
Parent relations can sometimes be useful but only if there is an actual 1 to many relation where the parent needs to exist.
Also note how keys are not foreign keys like in traditional SQL databases as they can exist without an entity. So you'll have to take care of consistency regardless of what you do.

Aggregation of cartesian product of two hierachical trees using Java

Need to do aggregation of Cartesian product of two hierarchical tree structures using Java, Please suggest some good methods or API to do this.
Tree Structure:
Country Tree :
Node|Id|ParentId
World|1|1
Asia|2|1
Europe|3|1
India|4|2
China|5|2
UK|6|3
Hungary|7|3
Cyprus|8|3
Profit Tree:
Node|Id|ParentId
Profit|1|1
Revenue|2|1
Expense|3|1
Cartesian product of these two products would give me 24 combinations (8 X 3). I need to aggregate values for each of the combination.
For example, I want to know Total revenue of Europe, Asia and World, Total Profit of Europe etc
It's a bit hard to answer without details of the structures. But I'll guess what they might be and you can extrapolate to your structures.
enum EconomicDataType {
PROFIT, REVENUE, EXPENSE;
}
interface GeographicNode {
int getEconomicData(EconomicDataType type);
}
class Region implements GeographicNode {
private List<GeographicNode> geographiesInRegion;
public int getEconomicData(EconomicDataType type) {
return geographiesInRegion.stream()
.mapToInt(geog -> geog.getEconomicData(type))
.sum();
}
}
class Country implements GeographicNode {
private EnumMap<GeographicNode, Integer> economicData;
public int getEconomicData(EconomicDataType type) {
return economicData.get(type);
}
}
I have modelled economic data as a map rather than a tree because, frankly, it makes no sense to me to make it a hierarchy given there's nothing hierarchical about the data.
I also haven't handled the situation in which data is missing. Not hard to add with a containsKey check before getting the data from the map.
Retrieving someing like total revenue for europe is:
europe.getEconomicData(EconomicDataType.REVENUE);
Simple :-)

Conditionally sort results in hibernate

Here are the tables that I'm working with. There is a User table that has some predefined columns ('name' in the example below) and an Extra Attributes table that used for making schema extension possible. The Extra Attributes table stores values for any new extended attributes as key-value pairs('title' and 'mobile' are the extra attributes in the example below) and the 'user' column is used for joining with the main User table. This arrangement generally works well for most operations, but I am not able to think of a way to sort on any of the extra attributes for the Users.
User Table:
---------------
id name
==============
1 jon
2 harry
Extra attributes table:
--------------------------------
user attr_key attr_value
================================
1 title engineer
1 mobile 111-2222-4444
2 title manager
2 mobile 111-0000-5555
Result of joining the two tables above(few columns intentionally skipped):
--------------------------------------------
id name attr_key attr_value
============================================
1 jon title engineer
1 jon mobile 111-2222-4444
2 harry title manager
2 harry mobile 111-0000-5555
I'm using hibernate for ORM. Here are the entity classes:
#Entity
public class User {
private Long id;
private String name;
private Set<ExtraAttributes> extraAttributes;
public String getName() {}
#OneToMany(mappedBy="user",fetch=FetchType.EAGER)
public Set<ExtraAttributes> getExtraAttributes() {}
...
}
#Entity
public class ExtraAttribute {
private Long id;
private String attrKey;
private String attrValue;
private User user;
...
#ManyToOne(optional = false)
public User getUser() {}
...
}
I want to be able to sort the results by attr_value corresponding to a specific attr_key, say 'title'. The problem is that if I order the results by attr_value then all the attr_values will be considered, while I want to order by only the attr_values that correspond to a specific attr_key - 'title'. I thought of ordering both by attr_key as well as attr_value but this doesn't seem to solve the problem either.

Design pattern for assembling disperate data?

I am designing a system which assembles disperate data in a standard row/column type output.
Each column can:
Exist in an independent system.
Can be paginated.
Can be sorted.
Each column can contain millions of rows.
And the system:
Needs to be extensible so different tables of different columns can be outputted.
The final domain object is known (the row).
The key is constant across all systems.
My current implementation plan is to design two classes per column (or one class column that implements two interfaces). The interfaces would:
Implement a pagination and sorting.
Implement "garnishing"
The idea is that the table constructor would receive information about the current sort column and page. Which would then return a list of appropriate keys for the table. This information would be used to create a list of the domain object rows which would then be passed in turn to each of the column "garnishing" implementations so that each columns information could be added in turn.
I guess my question is - what design patterns would be recommended - or alternative design decisions would people use for assembling disperate data with common keys and variable columns.
I'm not sure if I completely understood what you're trying to do, but from what I gather, you want to store rows of arbitrary data in a way that will allow you to make structured tables from it later on. What I would do in this case (assuming you're using Java) is make a very simple Column interface that would just have a "value" property:
public interface Column {
String value;
}
Then, you could make columns by implementing Column:
public class Key implements Column {
String value = new String();
public Key(String keyValue){
this.value = keyValue;
}
}
So then you can make a class called DataRow (or whatever you like) whose objects would contain the actual data. For example, you could have a method in that class that would allow you to add data:
public class DataRow {
List<Column> data = new ArrayList<Column>();
public DataRow(String key){
this.setColumn(new Key(key));
}
public void setColumn(Column columnData) {
this.data.add(columnData);
}
public Column getColumn(Class column){
for(Column c : this.data){
if(c.getClass().equals(column)){
return c;
}
}
return null;
}
}
As you can see, you can call the method setColumn() by giving it a new Column object. This will allow you to add any data you like of any type to the DataRow Object. Then, to make some tables, you could have a function that takes a List of DataRows, and a List of classes, that would then return only the objects which have data from the row specified:
public List<DataRow> createTable(List<DataRow> data, List<Class<? extends Column>> columns){
List<DataRow> table = new ArrayList<DataRow>();
for(DataRow row : data){
DataRow ret = new DataRow(row.getColumn(Key.class).value);
for(Class column : columns){
if(row.getColumn(column.getClass()) != null )ret.setColumn(row.getColumn(column.getClass()));
}
table.add(ret);
}
return table;
}
This will allow you to "create" tables using your data, and the columns you want to include in the table.
Note that I wrote this code to convey an idea, and that it's pretty messy at the moment. But I hope this will help you in some small way.

Same dataset, two different JTables

I have some data I have to show through two JTables; the data is the same, but each table will have to show it a little differently.
Also, I receive the data from an external connection (JMS in this case, but it doesn't really matter, it could be a DB, or whatever).
Being that I am new to Swing, I am still a little confused about who should fire the events, who should listen to them and how to make so that for a modification to my dataset I will have both the tables to update.
Now, a little example of my dataset structure as well as some dummy data:
class Student{ String name; Classroom classroom; boolean goodStudent}
class Classroom{ Sting name; List<String> coursesTaught; List<Student> students;}
public List<Classroom> classes;
Basically, my dataset will be the classes field in a Controller class and the two JTables will have to show things in different ways.
Namely, Table1 will have to show something like:
Classroom Name | Courses
4a | CS101, CS102, CS103
4b | BM101, CS102
4c | I101, CS4100
So basically, for each Classroom, the list of courses.
Table2 should instead show things like:
Student Name | Good?
Mark Spencer | true
Philippe Mann | true
Tom Sayer | false
I should see ALL the students, from all classrooms.
As you can see, the data is the same, but it is shown in different way.
What I would like to do is that, when my data changes, the tables will automatically update too.
For what I understood so far, I will have to subclass AbstractTableModel and create two different TableModels for the kind of data I want to show; what I don't get is:
How will the Models get their data, once some change happens?
Who should notify the models of this change?
Is it enough to call "fireTableXXXEvent()" to trigger the view refresh?
I hope I made myself clear enough...
In any case, thank you very much!
Bye
#StanislavL is right about needing a TableModel for each JTable, but nothing says they can't usefully descend from a common, abstract parent. In the (somewhat contrived) outline below, the two models share a common getColumnCount() implementation, while the concrete children implement the remaining required TableModel methods.
abstract class SchoolModel extends AbstractTableModel {
#Override
public int getColumnCount() { return 2; }
}
class ClassroomModel extends SchoolModel {
#Override
public int getRowCount() {…}
#Override
public Object getValueAt(int rowIndex, int columnIndex) {…}
}
class StudentModel extends SchoolModel {
#Override
public int getRowCount() {…}
#Override
public Object getValueAt(int rowIndex, int columnIndex) {…}
}
You are right. You need 2 AbstractTableModels.
Suppose you have the list List classesList classes as main data source. The first model row count will just return size() of the list. The second one will return sum of Students counts for each classroom. Column count for both models is 2. The inteeresting methods are getValueAt/setValueAt you have to find proper row. For the first list it's easy just appropriate list item. For the second table model you have to calculate proper row and then iterate through the list of Students.
Suppose something is changed in DB. You retrieve a new List. You can either find what's changed, which rows/cols were inserted/removed/changed or just replase the data source list in both models and fire structure changed event to let JTable completely refresh content.
Thre is no automatic update of models. You can write e.g. timer to check the changes each second/minute/hour or refresh on reopening the dialog/frame where the table is shown.

Categories