The expected functionality is that a user/vehicle interacts with a ParkingLot and it allots the space in Park method based on type of vehicle (here I can expect a few changes, like increase from regular and handicapped to one more functionality for celebrities etc). What would be the route to perfect object oriented code?class Vehicle attr_accessor :regno,:type def initialize(regno,type)     @regno=regno     @type=type endendclass ParkingLot attr_accessor :size , :handicapped_size , :regular_size  def initialize(size)    @lot={}    @size=size    @handicapped_size=(0.1)*size    @regular_size=size-@handicapped_size end def check_regular    @regular_size>0 ? @regular_size-=1 : false end def check_handicapped    @handicapped_size>0 ? @handicapped_size-=1 : false end def park(vehicle,hour)    case vehicle.type    when regular        check_regular ? @lot[vehicle.regno]=Regular_ParkingSpace.new(hour).payment : error()    when handicapped        check_handicapped ? @lot[vehicle.regno]=Handicapped_ParkingSpace.new(hour).payment : error()    end end def unpark(vehicle)    pay=@lot[vehicle.regno]    puts Pls pay us #{pay} rupees    @lot.delete(vehicle.regno){|el| puts #{el} not found in this parking lot \n} end def error    raise No more vehicles can be parked !! \n endendclass ParkingSpace attr_accessor :hour,:rate def initialize(hour,rate)    @hour=hour    @rate=rate end def payment    @hour * @rate endendclass Regular_ParkingSpace < ParkingSpace def initialize(hour,rate=20)    super end def payment    super endendclass Handicapped_ParkingSpace < ParkingSpace def initialize(hour,rate=5)    super endendPlease  mention the principle in use too.
Parking lot and vehicle classes
object oriented;ruby
Since @Flambino critiqued your existing code, I will focus more on application architecture.When I approach this subject, first I determine what things are interacting in the system.Parking lotsVehiclesParking fees (of which there are unrestricted and handicapped)PaymentsParking spaces (of which there are unrestricted and handicapped)This gives us 5 classes. Classes are nouns (people, places or things) and methods are the verbs (actions). We will throw in two more classes to descibe the permits a vehicle can have (a handicapped sticker for those in the USA) and a custom error class for more intelligent error handling in the application.VehicleParkingFeeParkingSpaceParkingSpacePaymentParkingLotVehiclePermitParkingSpaceErrorWe'll get the easiest one of of the way:class ParkingSpaceError < StandardErrorendNow we've got a specific error class when problems arise parking or paying for a parking spot allowing more intelligent error handling.Once I've identified the basic things in the system, I think of how they are related. The first class I build is the one with no relations to anything. It's quick and simple: The ParkingFee class.The ParkingFee classA parking fee consists of a rate multiplied by how many hours you've parked. Plus, you only have two rates. We will create static properties for both fee types that we can reference later:class ParkingFee  def self.unrestricted    @@unrestricted ||= ParkingFee.new 20  end  def self.handicapped    @@handicapped ||= ParkingFee.new 5  end  def initialize(rate)    @rate = rate;  end  def calculate(hours)    rate * hours  end  def rate    @rate  endendEasy peasy, rice and cheesey. The next class that's easy to create is the VehiclePermit class.The VehiclePermit classSince you must determine whether or not a vehicle is a handicapped vehicle, this got me thinking. First, I'm assuming since you reference rupees in your post that you are in India, or are building software that will be used in India. In the USA, vehicles can have multiple additional attributes describing how they can be used, and where they can be parked. I believe the term that we use is permit.Without understanding how vehicles are registered as handicap vehicles in India, I'll call this next class VehiclePermit. As we will see later, every Vehicle could have multiple permits attached to it. A handicapped vehicle is just a Vehicle that has the handicapped VehiclePermit associated with it.This class doesn't have much to it. An id and a name, plus a static property for convenience. This could be just as easily mapped from a database if you want.class VehiclePermit  def self.handicapped    @@handicapped ||= VehiclePermit.new 1, Handicapped  end  def initialize(id, name)    @id = id;    @name = name;  end  def id    @id  end  def name    @name  endendNow we can move on to the thing this is all about: vehicles.The Vehicle classThis class needs one or more permits, and a registration number. Still, not very complex. We'll also expose a public method to test this vehicle to see if it has the handicapped permit, which we will use later when parking the vehicle.class Vehicle  def initialize(registration_number)    @registration_number = registration_number    @permits = []  end  def is_handicapped?    @permits.any? {|p| p == VehiclePermit.handicapped }  end  def permits    @permits  end  def registration_number    @registration_number  endendWe have our ParkingFee, VehiclePermit and Vehicle, now we are ready to park this thing.The ParkingSpace classThe ParkingSpace class holds a vehicle, the date and time the vehicle parked, and the fee associated with it. It allows you to calculate the payment as well. We'll define public methods for all the actions you can perform on a parking space:Park a carVacate the spaceCalculate the feeTest to see if a vehicle is currently occupying itTest to see if it contains a particular vehicleTest a vehicle to see if it can park hereThe code:class ParkingSpace  def initialize(parking_lot, fee, number)    @parking_lot = parking_lot    @fee = fee    @number = number  end  def payment    ParkingSpacePayment.new self  end  def can_park?(vehicle)    !occupied?  end  def contains?(vehicle)    self.vehicle == vehicle  end  def number    @number  end  def occupied?    !vehicle.nil?  end  def park(vehicle)    raise ParkingSpaceError Cannot park vehicle #{vehicle.registration_number} unless can_park? vehicle    self.vehicle = vehicle    date_occupied = DateTime.current  end  def vacate    payment = nil    date_occupied = nil    vehicle = nil  end  def vehicle    @vehicle  endprivate  def payment=(new_payment)    @payment = new_payment  end  def calculate_fee(date)    fee.calculate(date)  end  def vehicle=(new_vehicle)    @vehicle = new_vehicle  endendWe aren't done yet, because there are two kinds of parking spaces. We will define concrete classes for each:class UnrestrictedParkingSpace < ParkingSpace  def initialize(parking_lot, number)    super(parking_lot, ParkingFee.unrestricted, number)  endendAn unrestricted parking space doesn't require much code. We just override the constructor to pass the proper ParkingFee object. The can_park? method on the parent class has the correct logic for this type of space, so we don't bother overriding it.class HandicappedParkingSpace < ParkingSpace  def initialize(parking_lot, number)    super(parking_lot, ParkingFee.handicapped, number)  end  def can_park?(vehicle)    super(vehicle) && vehicle.is_handicapped?  endendThe handicapped parking space overrides the constructor, which passes the handicapped fee, and overrides the can_park? method. The can_park? method first delegates to the method on the super class, and if that returns true, we have an additional test to see if the vehicle has a handicapped permit, so we also call Vehicle#can_park?.Each type of parking space has the fee baked in so no one can make the Unrestricted parking space fee less that 20 Rupees. Now that we've got a parking spaces, we need some place to put them: the ParkingLot.The ParkingLot classA parking lot has a bunch of spaces, both unrestricted and handicapped. We also need to do the following things in the parking lot:Park a vehicleExit the parking lotCalculate a payment for a vehicleCheck to see if spaces are availableThe constructor for the ParkingLot class takes two arguments: the number of unrestricted spaces and the number of handicapped spaces.class ParkingLot  def initialize(unrestricted_count, handicapped_count)    count = 0    @parking_spaces = []    unrestricted_count.times do |n|      @parking_spaces << UnrestrictedParkingSpace.new self, n    end    count = @parking_spaces.count    handicapped_count.times do |n|      @parking_spaces << HandicappedParkingSpace.new self, count + n    end  end  def exit(vehicle, payment)    parking_space = parking_space_for vehicle    raise ParkingSpaceError Balance not paid: #{payment.balance} unless payment.paid?    parking_space.vacate vehicle    parking_space  end  def park(vehicle)    index = @parking_spaces.index {|space| space.can_park? vehicle }    raise ParkingSpaceError No spaces available if index < 0    parking_space = @parking_spaces[index]    parking_space.park vehicle    parking_space  end  def payment_for(vehicle)    parking_space_for(vehicle).payment  end  def spaces_available?(vehicle = nil)    if vehicle.nil?      @parking_spaces.any? {|space| !space.occupied? }    else      @parking_spaces.any? {|space| space.can_park? vehicle }    end  endprivate  def parking_space_for(vehicle)    index = @parking_spaces.index {|space| space.contains? vehicle }    raise ParkingSpaceError Vehicle #{vehicle.registration_number} is not parked in this lot if index < 0    @parking_spaces[index]  endendLastly, let's pay for our spot using a ParkingSpacePaymentThe ParkingSpacePayment classThis class contains all the logic for paying for a parking spot. It needs the parking space, vehicle and fee. All three things are provided by the ParkingSpace object, so we require this in the constructor.class ParkingSpacePayment  def initialize(parking_space)    @parking_space = parking_space    @payment_date = DateTime.current    @total_hours = ((@payment_date - parking_space.date_occupied) / 1.hour).round    @amount_due = @parking_space.calculate_fee @total_hours    @amount_paid = 0  end  def amount_due    @amount_due  end  def amount_paid    @amount_paid  end  def balance    @amount_due - @amount_paid  end  def paid?    @amount_paid <= 0  end  def parking_space    @parking_space  end  def pay(amount)    @amount_paid += amount    balance  end  def payment_date    @payment_date  end  def total_hours    @total_hours  endendUsing these classes to manage a parking lotNow that we've got all the pieces built, let's see how we can park a car, and pay for it.begin  # Our parking lot as 10 unrestricted spaces and 5 handicapped spaces  parking_lot = ParkingLot.new 10, 5  # Create two vehicles, one of each type.  unrestricted_vehicle = Vehicle.new 1  handicapped_vehicle = Vehicle.new 2  handicapped_vehicle.permits << VehiclePermit.handicapped  # Park the cars  parking_lot.park unrestricted_vehicle  parking_lot.park handicapped_vehicle  # Let's do some shopping.  sleep 3.hours  # Time to check out.  unrestricted_payment = parking_lot.payment_for unrestricted_vehicle  handicapped_payment parking_lot.payment_for handicapped_vehicle  # 20 * 3 hours should be 60. Opps! This could be a problem later  unrestricted_payment.pay 55  # 5 * 3 hours = 15  handicapped_payment.pay 15  # I guess we went to the ATM. Whew!  unrestricted_payment.pay 5 unless unrestricted_payment.paid?  # Now let's exit the parking lot. Time to go home.  unrestricted_space = parking_lot.exit unrestricted_vehicle, unrestricted_payment  puts unrestricted_space.occupied? # -> false  handicapped_space = parking_lot.exit handicapped_vehicle, handicapped_payment  puts handicapped_space.occupied? # -> falserescue ParkingSpaceError => parking_error  puts Oops! Had a problem parking a car: #{parking_error}else Exception => e  raise e # A non parking error occurred.endExtra CreditSince a parking lot could have multiple levels and rows on each level, the layout of a parking lot could be abstracted away to a ParkingLotLayout class, which takes a ParkingLot as a constructor argument and defines the floors and rows that are available.