Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
0804804
Pseudocode for class booking
brendarios Mar 6, 2018
94645f7
Tests created for booking class however I expect more tests.
brendarios Mar 6, 2018
e902fdf
Tests created for helper method reservations per day in booking.
brendarios Mar 6, 2018
5386cb8
Rakefile and specs/spec_helper created.
brendarios Mar 6, 2018
300d747
Implementation of class Booking with methods -add reservation- and -r…
brendarios Mar 6, 2018
b9bb52b
Tests for class Reservation created.
brendarios Mar 6, 2018
5daf160
Implementation of class Reservation with constructor and cost_reserva…
brendarios Mar 6, 2018
cdbdcca
Tests and class DatesRange created. Still need to implement a method …
brendarios Mar 8, 2018
f7e8471
Modified some variables names
brendarios Mar 8, 2018
1bf0abf
Tests created for class Room.Will probably need to add or modify.
brendarios Mar 8, 2018
5d595e0
class Rooms is created
brendarios Mar 8, 2018
b1177e8
Update on the tests for class Rooms.
brendarios Mar 8, 2018
7fa700a
Add parameter room number to Reservation class
brendarios Mar 9, 2018
296bf69
Refactor tests for Reservation class
brendarios Mar 9, 2018
36e7317
Refactor and added to raise an ArgumentError when rooms are not avail…
brendarios Mar 9, 2018
859fe65
Added some tests and refactor others for Booking class.
brendarios Mar 9, 2018
968b421
Refactored Reservation class, I was missing to initialize the room_nu…
brendarios Mar 9, 2018
44ac8d6
Refactored design of class and eliminated Rooms class.
brendarios Mar 9, 2018
6e26ec7
Refactor made to Booking and reservation class. Now all tests passing.
brendarios Mar 9, 2018
a692489
Tests created for new class BlockRooms and created file for class Blo…
brendarios Mar 10, 2018
f6334bf
Implementation of methods for class BlockRooms.
brendarios Mar 10, 2018
6690d4e
Tests for class BlockRooms passing.
brendarios Mar 10, 2018
29265b6
Pseudocode for a method to create a block of rooms in Booking and Tes…
brendarios Mar 10, 2018
bf402d4
Method capacity_for_block_rooms? in Booking was implemented and tests…
brendarios Mar 10, 2018
96d7d27
Pseudocode for method building_block_rooms method to reserve block ro…
brendarios Mar 10, 2018
7e7b0cb
Implementation of building_block_rooms method and tests passing.
brendarios Mar 11, 2018
699bad3
little refactor to reservation class and its tests.
brendarios Mar 11, 2018
f5429d3
Refactor of tests for DatesRange class.
brendarios Mar 11, 2018
05017e5
For design purposes I decided to don't use Rooms class therefore, the…
brendarios Mar 11, 2018
d9eb235
cleaning of comments and adjusted spacing for final commit.
brendarios Mar 12, 2018
c10b546
Design-activity file was created and answered.
brendarios Mar 31, 2018
6925094
Fixed the constants names as suggested in feedback.
brendarios Mar 31, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
9 changes: 9 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
require 'rake/testtask'

Rake::TestTask.new do |t|
t.libs = ["lib"]
t.warning = true
t.test_files = FileList['specs/*_specs.rb']
end

task default: :test
89 changes: 89 additions & 0 deletions design-activity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
What classes does each implementation include? Are the lists the same?
Each implementation have 3 classes: CartEntry, ShoppingCart, and Order.

Write down a sentence to describe each class.

Implementation A
Class CartEntry: assign the value of the variables unit_price and quantity and gives access to them from outside the class.
Class ShoppingCart: assign the value of the variable entries and gives access to it from outside.
Class Order: instantiate a new instance of ShoppingCart and calculates the total price of all the entries in the cart.

Implementation B
Class CartEntry: assign the value of the variables unit_price and quantity and calculates the price of each item according to its quantity.
Class ShoppingCart: assign the value of the variable entries and calculates the price of all the entries in the shopping cart.

Class Order: instantiate a new instance of ShoppingCart and calculates the total price of all the entries in the cart plus the sales tax using a helper method "price" from the ShoppingCart class.

How do the classes relate to each other? It might be helpful to draw a diagram on a whiteboard or piece of paper.

Implementation A:
Class CartEntry and class ShoppingCart does not relate to each other but then all 3 classes relate to class Order.
Class Order has-a ShoppingCart instance which has a collection of entries coming from class ShoppingCart. Also, class CartEntry provides to the class Order, the unit_price and quantity of each entry.

Implementation B:
The class Order has-a ShoppingCart instance that provides a collection of entries each one with its own price that is provided by a helper method price in class CartEntry.

What data does each class store? How (if at all) does this differ between the two implementations?
Implementation A:
CartEntry: values of unit_price and quantity.
ShoppingCart: collection of entries.
Order: new cart and the total price of all the entries in the cart including the taxes.

Implementation B:
CartEntry: values of unit_price and quantity
ShoppingCart: collection of entries and the sum of the price of all the entries together.
Order: new cart and the total price of all the entries in the cart including the taxes. Also stores the constant SALES_TAX.

What methods does each class have? How (if at all) does this differ between the two implementations?

Implementation A:
Class CartEntry: constructor method
Class ShoppingCart: constructor method
Class Order: constructor method and total_price method.

Implementation B:
Class CartEntry: constructor method and price method.
Class ShoppingCart: constructor method and price method.
Class Order: constructor method and total_price method.


Consider the Order#total_price method. In each implementation:
Is logic to compute the price delegated to "lower level" classes like ShoppingCart and CartEntry, or is it retained in Order?

Implementation A:
The logic for price is retained in Order.

Implementation B:
The logic for price is delegated to lower level classes like ShoppingCart and CartEntry

Does total_price directly manipulate the instance variables of other classes?
Implementation A:
Yes, the method total_price in class Order manipulates all the instance variables of the other classes.

Implementation B:
No, it does not manipulates directly the instance variables but it does indirectly as it manipulates a helper method from class ShoppingCart, and this price method does manipulate instance variables.


If we decide items are cheaper if bought in bulk, how would this change the code? Which implementation is easier to modify?

The price of the items depending on the quantity will change so, this will be easy to change in Implementation B at the helper method price by adding a conditional so that in case of a certain quantity the price will change.
Doing this in Implementation A will be more complicated because it will need to be changed the method total_price in the class Order by adding a conditional there.

Which implementation better adheres to the single responsibility principle?

Implementation B.

Bonus question once you've read Metz ch. 3: Which implementation is more loosely coupled?

Implementation B because class CartEntry does not depend on class ShoppingCart or viceversa, and in implementation A, class Order is very dependent of the other classes.

-------------------------------

MY HOTEL PROJECT:
In my Hotel project I have 4 classes each of them with a responsibility:
Booking: to control the reservations of individual and blocked rooms.
Reservation: to calculate the cost of a reservation.
DatesRange: to validate the staying time of a guest.
BlockRooms: to calculate the total cost of a block room when available.

Overall, I think all of my classes have state and behavior.
Binary file added lib/.DS_Store
Binary file not shown.
26 changes: 26 additions & 0 deletions lib/blockrooms.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module Hotel

class BlockRooms

def initialize(checkin, checkout, blocked_rooms, discounted_rate)
@price_per_night = discounted_rate.to_f
@days_range = Hotel::DatesRange.new(checkin, checkout)
@blocked_rooms = blocked_rooms
end

def available_room_in_block?
@blocked_rooms.length > 0 ? true : false
end

def reservation_block_room
raise ArgumentError.new("Unavailable blocked rooms") if !available_room_in_block?
@blocked_rooms.delete_at(0)
return @blocked_rooms
end

def total_cost_block_room
(@price_per_night * @days_range.amount_days)
end

end
end
84 changes: 84 additions & 0 deletions lib/booking.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
module Hotel

AMOUNT_ROOMS_HOTEL = 20
MAX_BLOCKED_ROOMS = 5

class Booking

attr_reader :rooms_list, :reservations_list
def initialize
@reservations_list = []
@rooms_list = {}
setup_rooms

end

def setup_rooms
AMOUNT_ROOMS_HOTEL.times do |num|
@rooms_list["#{num + 1}"] = []
end
end

def is_available?(room_number, dates_to_reserve)
is_available = true

@rooms_list[room_number].each do |dates|
if dates_to_reserve.overlap?(dates)
is_available = false
end
end
return is_available
end

def avaliable_rooms_daterange(checkin, checkout)
list_availables = []
date_range = Hotel::DatesRange.new(checkin,checkout)
@rooms_list.each do |room_number, dates|
if is_available?(room_number, date_range)
list_availables << room_number
end
end
return list_availables
end

def add_reservation(checkin, checkout)
dates_to_reserve = Hotel::DatesRange.new(checkin, checkout)
@rooms_list.each do |room_number, dates|
if is_available?(room_number, dates_to_reserve)
@rooms_list[room_number] << dates_to_reserve
new_reservation = Hotel::Reservation.new(checkin, checkout, room_number)
@reservations_list << new_reservation
return new_reservation
end
end
raise ArgumentError.new("Sorry!, No rooms available during that date range")
end

def reservations_per_day(date)
reservations_list_per_day = []
@reservations_list.each do |reservation|
if reservation.range_of_dates.include?(date)
reservations_list_per_day << reservation
end
end
return reservations_list_per_day
end

def capacity_for_block_rooms?(checkin, checkout, num_rooms_to_block)
raise ArgumentError.new('The maximum of rooms to block is 5') if num_rooms_to_block > MAX_BLOCKED_ROOMS
return true if avaliable_rooms_daterange(checkin, checkout).length >= num_rooms_to_block
return false
end

def building_block_rooms(checkin, checkout, num_rooms_to_block, discounted_rate)
array_rooms_blocked = []
if capacity_for_block_rooms?(checkin, checkout, num_rooms_to_block)
num_rooms_to_block.times do
reservation_block_room = add_reservation(checkin, checkout)
array_rooms_blocked << reservation_block_room.room_number
end
end
return Hotel::BlockRooms.new(checkin, checkout, num_rooms_to_block, discounted_rate)
end
end
end
34 changes: 34 additions & 0 deletions lib/dates.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
module Hotel

class DatesRange

attr_reader :checkin, :checkout

def initialize(start_date, end_date)
@checkin = start_date
@checkout = end_date
date_validation
end

def date_validation
return true if @checkin < @checkout
raise ArgumentError.new("Your date is not a valid input")
end

def amount_days
(@checkout - @checkin).to_i
end

def include?(date)
return true if @checkin <= date && @checkout > date
return false
end

def overlap?(another)
return true if another.checkin <= self.checkin && another.checkout > self.checkin
return true if another.checkin >= self.checkin && another.checkin < self.checkout
return false
end

end
end
20 changes: 20 additions & 0 deletions lib/reservation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module Hotel

PRICE_PER_NIGHT = 200

class Reservation

attr_reader :checkin, :checkout, :range_of_dates, :room_number

def initialize(checkin, checkout, room_number)
@price_per_night = PRICE_PER_NIGHT
@range_of_dates = Hotel::DatesRange.new(checkin, checkout)
@room_number = room_number
end

def cost_reservation
(@price_per_night * @range_of_dates.amount_days).to_f
end

end
end
Binary file added specs/.DS_Store
Binary file not shown.
57 changes: 57 additions & 0 deletions specs/blockrooms_specs.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
require_relative 'spec_helper'
require 'pry'

describe 'BlockRooms class' do
before do
@start_date = Date.new(2018, 8, 20)
@end_date = Date.new(2018, 8, 27)
@blocked_rooms = [1,2,3,4]
@discounted_rate = 130.50
@new_block = Hotel::BlockRooms.new(@start_date, @end_date, @blocked_rooms, @discounted_rate)
end

describe 'Initialize' do
it "Can be created" do
@new_block.must_be_instance_of Hotel::BlockRooms
end
end

describe "available_room_in_block? method" do

it 'returns false if no rooms available in the blocked rooms set' do
4.times do
@new_block.reservation_block_room
end
@new_block.available_room_in_block?.must_equal false
end

it 'returns true if they are rooms available in the blocked rooms set' do
@new_block.available_room_in_block?.must_equal true
end
end

describe "reservation of block rooms method" do

it "modifies blocked_rooms when a new reservation of a block room is created" do
@new_block.reservation_block_room.must_equal [2, 3, 4]
@new_block.reservation_block_room.must_equal [3,4]
@new_block.reservation_block_room.must_be_kind_of Array
end

it 'raises an error if no more blocked rooms are available' do
4.times do
@new_block.reservation_block_room
end
proc{@new_block.reservation_block_room}.must_raise ArgumentError
end
end

describe "total_cost_block_room method " do

it 'Returns the total cost for reservation of a blocked room' do
@new_block.total_cost_block_room.must_be_kind_of Float
@new_block.total_cost_block_room.must_equal 913.50
end

end
end
Loading