The document discusses code smells, which are surface indications that may suggest deeper problems in the code. It lists several types of code smells such as long methods, large classes, primitive obsession, and duplicate code. It then provides examples of refactoring code to eliminate code smells by improving structure, reducing complexity, increasing readability and modifying classes, methods and names for better organization and design.
9. class OrdersReport
def initialize(orders, start_date, end_date)
@orders = orders
@start_date = start_date
@end_date = end_date
end
def total_sales_within_date_range
orders_within_range =
@orders.select { |order| order.placed_at >= @start_date &&
order.placed_at <= @end_date }
orders_within_range.
map(&:amount).inject { |sum, amount| amount + sum }
end
end
class Order < OpenStruct
end
10. class OrdersReport
def initialize(orders, start_date, end_date)
@orders = orders
@start_date = start_date
@end_date = end_date
end
def total_sales_within_date_range
orders_within_range.
map(&:amount).inject { |sum, amount| amount + sum }
end
private
def orders_within_range
@orders.select { |order| order.placed_at >= @start_date &&
order.placed_at <= @end_date }
end
end
class Order < OpenStruct
end
11. class OrdersReport
def initialize(orders, start_date, end_date)
@orders = orders
@start_date = start_date
@end_date = end_date
end
def total_sales_within_date_range
orders_within_range.
map(&:amount).inject { |sum, amount| amount + sum }
end
private
def orders_within_range
@orders.select { |order| order.placed_between?(@start_date, @end_date) }
end
end
class Order < OpenStruct
def placed_between?(start_date, end_date)
placed_at >= start_date && placed_at <= end_date
end
end
12. class OrdersReport
def initialize(orders, date_range)
@orders = orders
@date_range = date_range
end
def total_sales_within_date_range
orders_within_range.
map(&:amount).inject { |sum, amount| amount + sum }
end
private
def orders_within_range
@orders.select { |order| order.placed_between?(@date_range) }
end
end
class DateRange < Struct.new(:start_date, :end_date)
end
class Order < OpenStruct
def placed_between?(date_range)
placed_at >= date_range.start_date && placed_at <= date_range.end_date
end
end
13. class OrdersReport
def initialize(orders, date_range)
@orders = orders
@date_range = date_range
end
def total_sales_within_date_range
orders_within_range.
map(&:amount).inject { |sum, amount| amount + sum }
end
private
def orders_within_range
@orders.select { |order| order.placed_between?(@date_range) }
end
end
class DateRange < Struct.new(:start_date, :end_date)
def include?(date)
(start_date..end_date).cover?(date)
end
end
class Order < OpenStruct
def placed_between?(date_range)
date_range.include?(placed_at)
end
end
19. 99 bottles of beer on the wall, 99 bottles of beer.
Take one down and pass it around, 98 bottles of beer on the wall.
98 bottles of beer on the wall, 98 bottles of beer.
Take one down and pass it around, 97 bottles of beer on the wall.
97 bottles of beer on the wall, 97 bottles of beer.
Take one down and pass it around, 96 bottles of beer on the wall.
…
2 bottles of beer on the wall, 2 bottles of beer.
Take one down and pass it around, 1 bottle of beer on the wall.
1 bottle of beer on the wall, 1 bottle of beer.
Take one down and pass it around, no more bottles of beer on the wall.
No more bottles of beer on the wall, no more bottles of beer.
Go to the store and buy some more, 99 bottles of beer on the wall.
20.
21. A satisfactory modular decomposition technique must satisfy one more requirement: It should yield
modules that are both open and closed.
• A module will be said to be open if it is available for extension. For example, it should be possible to add
fields to the data structures it contains, or new elements to the set of functions it performs.
• A module will be said to be closed if is available for use by other modules. This assumes that the module
has been given a well-defined, stable description (the interface in the sense of information hiding). In the
case of a programming language module, a closed module is one that may be compiled and stored in a
library, for others to use. In the case of a design or specification module, closing a module simply means
having it approved by management, adding it to the project's official repository of accepted software
items (often called the project baseline), and publishing its interface for the benefit of other module
designers.
Robert C. Martin
SOLID