AdSense

Showing posts with label OOD. Show all posts
Showing posts with label OOD. Show all posts

Friday, March 27, 2015

Design Hotel Reservation


Design a hotel reservation system. To make it simple, we assume that the hotel has only one building and the building has only one floor. Design your objects so that they work better with a non-sql database, say a document-oriented database.

The reservation system needs at least two another class. The first one is the Room class, which is identified by the room number and have several methods such as book() or unbook().

The second one is the Customer class. This class contains the information of a customer who has made a reservation.

I also use two maps to store all rooms and customers. The reason to use map is that it is easy for retrieval: I can use the name and room number to find the customer and room I want.

Two public methods: makeReservation and cancelReservation.

makeReservation() will create a Customer object, find the next available room, and assign that to the customer, so when the customer checks in, he/she can easily find the room. If there is no available room, then no reservation can be made.

cancelReservation() will remove the Customer object c out of the customers map and make the room available.

There are couple private helper methods that I don't want to go detail.


public class ReservationSystem{
 final Map rooms;
 Map customers;
 
 public ReservationSystem(List builtRoom){
  rooms = new HashMap ();
  //when the hotel is built, all the rooms are added into the system
  rooms.add(builtRoom);
  customers = new HashMap ();
 }
 
 public boolean makeReservation(String name, String id, String information){
  int room = findNextAvailableRoom();
  if(room == -1){
   System.out.println("No available room!");
   return false;
  }
  Customer c = new Customer(name, id, information, room);
  rooms.get(room).book();
  customers.put(name, c);
  return true;
 }
 
 public boolean cancelReservation(String name){
  Customer c = findCustomer(name);
  if(c == null){
   System.out.println("No reservation found!");
   return false;
  }
  customers.remove(name);
  makeAvailable(c.roomBooked);
  return true;
 }
 
 private Customer findCustomer(String name){
  if(!customers.containsKey(name))
   return null;
  return customers.get(name);
 }
 
 private void makeAvailable(int roomNumber){
  rooms.get(roomNumber).unbook();
 }
 private int findNextAvailableRoom(){
  for(Room r : rooms.values()){
   if(!r.isBooked())
    return r.roomNumber;
  }
  return -1;
 }
 
 
 class Room{
  final int roomNumber;
  private boolean available;
  
  public Room(int rN){
   roomNumber = rN;
   available = true;
  }
  
  public void book(){
   available = false;
  }
  void unbook(){
   available = true;
  }
  public boolean isBooked(){
   return !available;
  }
 }
 
 class Customer{
  String name;
  String id;
  String information;
  int roomBooked;
  
  public Customer(String name, String id, String information, int roomNumber){
   this.name = name;
   this.id = id;
   this.information = information;
   roomBooked = roomNumber;
  }
 }

Sunday, March 22, 2015

Design a chat server


Explain how you would design a chat server.In particular, provide details about the various backend components, classes, and methods.What would be the hardest problems to solve? 

The fun part of OOD is that you can add any feature you want to the project as long as it's logical. This problem, we need a user class, which has some basic features such as sending requests, approve/deny requests, send messages, add users, etc. We also need a server class which is pretty much the database of all users. 

There are lots of limitations to the class I design. I am not quite familiar with server, so I cannot say mush. 


enum StatusType{
 online, offline, away;
}
class Status{
 StatusType status_type;
 String status_message;
}
class User{
 String username;
 String display_name;
 List contactList;
 List requests;
 StatusType currentStatus = StatusType.offline;
 String status;
 private Server belongsTo;
 private Map> messageBox;
 public User(Server belongsTo, String userName){
  this.belongsTo = belongsTo;
  username = userName;
  contactList = new ArrayList ();
  requests = new ArrayList ();
  messageBox = new HashMap> ();
  
 }
 boolean updateStatus(String message){
  status = message;
 }
 boolean sendRequest(String userName){
  if(!belongsTo.userExists(userName)){
   System.out.println("No such user!");
   return false;
  }
  User toAdd = belongsTo.getUser(userName);
  ConnectRequest send = new ConnectRequest(this, toAdd);
  toAdd.requests.add(send);
  return true;
 }
 boolean approveRequest(Request r){
  //user deactivates the account before the request is approved
  if(!belongsTo.contains(r.receiver){
   System.out.println("No such user!");
   return false;
  }
  User toAdd = belongsTo.get(r.receiver);
  contactList.add(toAdd);
  requests.remove(r);
  return true;
 }
 boolean denyRequest(Request r){
  requests.remove(r);
  return true;
 }
 void removeContact(String userName){
  User toRemove = belongsTo.get(userName);
  contactList.remove(toRemove);
 }
 boolean sendMessage(String username, String message){
  User toBuzz = belongsTo.get(username);
  if(!contactList.contains(toBuzz)){
   System.out.println("The user is not in your contact list!");
   return false;
  }
  if(toBuzz.status == StatusType.offline){
   System.out.println("User is currently offline!");
   return false;
  }
  if(!messageBox.contains(toBuzz)){
   messageBox.put(toBuzz, new ArrayList());
   toBuzz.messageBox.put(this, new ArrayList());
  }
  messageBox.get(toBuzz).add(message);
  toBuzz.messageBox.get(this).add(message);
  return true;
 }
 void setStatus(StatusType s){
  currentStatus = s;
 }
 
}
class ConnectRequest{
 User sender;
 User receiver;
}
class Server{
 List dataBase;
 boolean userExists(String userName){
  for(User u : dataBase){
   if(u.userName.equals(userName))
    return true;
  }
  return false;
 }
 void registration(String userName){
  if(userExists(userName){
   System.out.println("user name exists, please change for another one");
  }
  dataBase.add(new User(this, userName));
 }
 void deactivate(String userName){
  dataBase.remove(getUser(userName));
 }
 User getUser(String userName){
  for(User u : dataBase){
   if(u.username = userName)
    return u;
  }
  return null;
 }
}

Monday, March 16, 2015

Design a music juke box

A music juke box will possibly need: a CD player, A set of CDs, a program to set tracks and a user.

The rule of OOD suggests that we should wrap up data with their operating functions in a single entity class, so we need to following classes"


  • JukeBox: Of course, that's what we are designing.
  • CD player: to play CDs
  • CD: well, to play
  • Playlist: a user defined playlist that allows the user to query the songs he/she wants to play
  • Song: yeah, it's music...
  • TrackSelector: that is the program to set and get the track
  • User: who is playing? The current design only allows for one user at a time. 


JukeBox:

public class JukeBox{
 private CDPlayer cdPlayer;
 private User user;
 private Set cdCollection;
 private TrackSelector ts;
 
 public JukeBox(CDPlayer cdPlayer, User user, Set cdCollection, TrackSelector ts){
 }
 public Song getCurrentTrack(){
  return ts.getCurrentSong();
 }
        public void setCurrentTrack(Song s){
  ts.setCurrentSong(s);
 }
 public void setNextTrack(Song s){
  ts.setNext(s);
 }
 public void processOneUser(User u){
  this.user = u;
 }
}


CD player:
CD player contains a playlist, the CD that it is currently playing, and the button to play a track.


public class CDPlayer{
 private Playlist p;
 private CD c;
 public Playlist getPlaylist(){
  return p;
 }
 public void setPlaylist(Playlist p){
  this.p = p;
 }
 public CD getCD(){
  return c;
 }
 public void setCD(CD c){
  this.c = c;
 }
 public CDPlayer(Playlist p){
  this.p = p;
 }
 public CDPlayer(CD c, Playlist p){
  
 }
 public CDPlayer(CD c){
  this.c = c;
 }
 public void playTrack(Song s){
 }
}

CD: 
Well, as you can imagine, a CD contains name, and list of songs. Of course we can also add artist, number of songs and so on, but just for simplicity, I only include the first two.


public class CDPlayer{
 private Playlist p;
 private CD c;
 public Playlist getPlaylist(){
  return p;
 }
 public void setPlaylist(Playlist p){
  this.p = p;
 }
 public CD getCD(){
  return c;
 }
 public void setCD(CD c){
  this.c = c;
 }
 public CDPlayer(Playlist p){
  this.p = p;
 }
 public CDPlayer(CD c, Playlist p){
  
 }
 public CDPlayer(CD c){
  this.c = c;
 }
 public void playTrack(Song s){
 }
}


Playlist:
A playlist will include, the CD that creates the play list and a queue of songs in the list.


public class Playlist{
 private CD cd;
 private Queue queue;
}


Song: 
The song, as you can imagine, may include the name of the song, lyrics the artist who create the song and so on.


public class Song{
 private String songName;
 private String lyrics;
 private String artist;
 public String getName(){
  return songName;
 }
}


TrackSelector: 
The track selector definitely allows us to select tracks, so it includes a song that is currently playing, set a song that the user wants to play next, switch the current playing song, and get the current playing song.


public class TrackSelector{
 private Song currentSong;
 private Song nextSong;
 //assume not playing any song at the beginning 
 public TrackSelector(){
  currentSong = "";
  nextSong = "";
 }
 public void setCurrent(Song s){
  currentSong = s;
 }
 public void setNext(Song s){
  nextSong = s;
 }
 public Song getCurrentSong(){
  return currentSong;
 }
}


User: 
The user will have a name (Who doesn't? ) and a unique ID.


public class User{
 private String name;
 private long ID;
 public User(String name, long id){
  this.name = name;
  ID = id;
 }
 public String getName(){
  return name;
 }
 public void setName(String name){
  this.name = name;
 }
 public long getID(){
  return ID;
 }
 public void setID(long id){
  ID = id;
 }
 public User getUser(){
  return this;
 }
}

Design a Call Center


Imagine you have a call center with three levels of employees: fresher, technical lead (TL), product manager (PM).There can be multiple employees, but only one TL or PM.An incoming telephone call must be allocated to a fresher who is free.If a fresher can’t handle the call, he or she must escalate the call to technical lead.If the TL is not free or not able to handle it, then the call should be escalated to PM.Design the classes and data structures for this problem.Implement a method getCallHandler() 

This is a more complicated problem, but there are lots of interesting parts.

First, we need the employee class, and three subclasses to handle fresher, TL and PM. Since except the rank, all three roles share the same information (duties, personal information, etc. ). We will focus on the function of the call center (receive calls) to design this class. So this class will have the following fields and methods:

A CallHandler object: the CallHandler class is the call coordinator we will discuss later.
int rank: the rank of the employee (0 for fresher, 1 for TL and 2 for PM).
boolean free: if the employee is free right now.
receiveCall(): method to receive a call
callHandled():complete a call
cannotHandle(): if the employee with the current rank cannot handle the call


class Employee{
 CallHandler callHandler;
 int rank;//0 - fresher, 1 - technical lead, 2 - product manager
 boolean free;
 Employee(int rank) {
  this.rank = rank;
 }
 void receiveCall(Call call){}
 void callHandled(Call call, String message){
  call.reply(message);
  call.disconnect();
  callHandler.getNextCall(this);
 }//complete call
 //If the employee with the current rank cannot handle the call
 void cannotHandle(Call call){
  //escalate the call to a higher rank
  call.rank = rank + 1;
  callHandler.dispatchCall(call);
  free = true;
  callHandler.getNextCall(this);
 }
}

class Fresher extends Employee{
 public Fresher() {super(0);}
}
class TechLead extends Employee{
 public TechLead() {super(1);}
}
class ProductManager extends Employee{
 public ProductManager() {super(2);}
}


Second, the CallHandler class, which is used to coordinate the calls. According to the problem statement, the call is first assigned to the available with the lowest rank, if the employee cannot handle the call, the call needs to be escalated to a higher rank person, if no higher rank employee is available, the call will be added to a queue. And the current employee will try to handle the next call.

LEVELS = 3: we have 3 levels of employees
NUM_FRESHERS: the number of freshers
List<Employee>[]: an array of employee list. We need all employee's information to know who is available for the call, the array has a length of 3, i.e., 3 levels.
Queue<Call>[]: the queue waiting list. If no one is available to take the call, let the call wait until the next available employee at current level.


public class CallHandler{
 static final int LEVELS = 3;
 static final int NUM_FRESHERS; //assume we have 5 freshers
 List[] employeeLevels;
 Queue[] callQueues;//enqueue waiting calls
 
 public CallHandler(int NUM_FRESHERS){
  this.NUM_FRESHERS = NUM_FRESHERS;
  employeeLevels = new ArrayList[LEVELS];
  callQueues = new LinkedList[LEVELS];
 }
 //return the first available person equal or higher than 
 //current call rank
 Employee getCallHandler(Call call){
  for(int level = call.rank; level < LEVELS - 1; level++){
   List employeeLevel = employeeLevels[level];
   for(Employee emp : employeeLevel){
    if(emp.free) return emp;
   }
  }
  return null;
 }
 void dispatchCall(Call call){
  //try to route the call to an employee with minimal rank
  Employee emp = getCallHandler(call);
  if(emp != null)
   emp.ReceiveCall(call);
  //if no one is available for the call, put the call on the queue
  //waiting for the next available employee
  else
   callQueues[call.rank].add(call);
 }
 //look for call at e's rank
 void getNextCall(Employee e){
  if(callQueues[e.level].size() != 0){
   Call next = callQueues[e.level].poll();
   e.receiveCall(next);
  }
 } 
}


Third, the Call class. This class is nothing special, we need it because, we need calls.


class Call {
 int rank = 0; // minimal rank of employee who can handle this call
 public void reply(String message) {}
 public void disconnect(){}//end call
}

Design a deck of cards

This is a traditional OOD problem. To start, a card has two elements: the suit, and the value. So we will have an enum class Suit, which contains CLUBS, SPADES, HEARTS and DIAMONDS. We will also have an integer value, cardValue to represent the value of the card (1 - 13).


public class Card{
 public enum Suit{
  CLUBS (1), SPADES (2), HEARTS (3), DIAMONDS (4);
  private Suit(int v) { value = v;}
 };
 private int cardValue;
 private Suit suit;
 public Card(int r, Suit s){
  cardValue = r;
  suit = s;
 }
 public int value() { return card };
 public Suit suit() { return suit };
}


Now if we want to build a blackjack game, we need to know the value of cards. Face cards are 10 and an ace is 11. So we need to extend the above class and override the the value() method.


public class BlackJackCard extends Card {
 public BlackJackCard(int r, Suit s) { super(r, s);}
 public int value() {
  int r = super.value();
  if(r == 1)
   return 11;//ace is 11
  if(r < 10)
   return r;
  return 10;
 }
}
boolean isAce(){
   return super.value() == 1;
}