Class: Reek::Smells::FeatureEnvy

Inherits:
SmellDetector show all
Defined in:
lib/reek/smells/feature_envy.rb

Overview

Feature Envy occurs when a code fragment references another object more often than it references itself, or when several clients do the same series of manipulations on a particular type of object.

A simple example would be the following method, which “belongs” on the Item class and not on the Cart class:

class Cart
  def price
    @item.price + @item.tax
  end
end

Feature Envy reduces the code’s ability to communicate intent: code that “belongs” on one class but which is located in another can be hard to find, and may upset the “System of Names” in the host class.

Feature Envy also affects the design’s flexibility: A code fragment that is in the wrong class creates couplings that may not be natural within the application’s domain, and creates a loss of cohesion in the unwilling host class.

Currently FeatureEnvy reports any method that refers to self less often than it refers to (ie. send messages to) some other object.

Constant Summary

Constants inherited from SmellDetector

SmellDetector::ENABLED_KEY, SmellDetector::EXCLUDE_KEY

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from SmellDetector

class_name, contexts, #examine, #exception?, listen, #smell_name

Constructor Details

#initialize(config = FeatureEnvy.default_config) ⇒ FeatureEnvy

Returns a new instance of FeatureEnvy.



41
42
43
# File 'lib/reek/smells/feature_envy.rb', line 41

def initialize(config = FeatureEnvy.default_config)
  super
end

Class Method Details

.default_configObject



37
38
39
# File 'lib/reek/smells/feature_envy.rb', line 37

def self.default_config
  super.adopt(EXCLUDE_KEY => ['initialize'])
end

Instance Method Details

#examine_context(context, report) ⇒ Object

Checks whether the given context includes any code fragment that might “belong” on another class. Any smells found are added to the report.



50
51
52
53
54
55
# File 'lib/reek/smells/feature_envy.rb', line 50

def examine_context(context, report)
  context.envious_receivers.each do |ref|
    report << SmellWarning.new(self, context,
                "refers to #{SexpFormatter.format(ref)} more than self")
  end
end