code smells

37
CODE SMELLS

Upload: leonardo-bernardelli

Post on 09-Apr-2017

30 views

Category:

Technology


0 download

TRANSCRIPT

CODE SMELLS

O QUE É UM CODE SMELL?

LEONARDO BERNARDELLI@lbenardelli

• Long Method • Large Class • Primitive Obsession • Long Parameter List • Data Clumps

• Switch Statements • Temporary Field • Refused Bequest • Alternative Classes with Different Interfaces

• Divergent Change • Shotgun Surgery • Parallel Inheritance Hierarchies

• Comments • Duplicate Code • Lazy Class • Data Class • Dead Code • Speculative Generality

• Feature Envy • Inappropriate Intimacy • Message Chains • Middle Man • Incomplete Library Class

BLOATERS

OO ABUSERS

CHANGE PREVENTERS

DISPENSABLES

COUPLERS

RefactoringPara todo existe uma receita

CODE SMELL

que explica como resolver o problema

http://www.industriallogic.com/wp-content/uploads/2005/09/smellstorefactorings.pdf

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

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

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

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

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

Foo Sale

Sale

where

.where(date: range)

Persistence

where

List

a List

a List

sum

.sum('cost')

Colaboradores Imediatos

FooDateRange

LIST

Sale

#where

I KNOW MY COLLABORATORS COLLABORATORS

SPECULATIVE GENERALITYDEPENDENCY INJECTION

É FODA!

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.

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

OBRIGADO!