Skip to main content
Code Review

Return to Answer

Commonmark migration
Source Link

###Choose Names at the Appropriate Level of Abstraction

Choose Names at the Appropriate Level of Abstraction

###Choose Names at the Appropriate Level of Abstraction

Choose Names at the Appropriate Level of Abstraction

Attempt to improve sentence accuracy
Source Link
jsuth
  • 857
  • 4
  • 17

What if XmlParser changes? What if we wanted to use a different kind of Parser? What if we wanted to construct a Fake object for testing and pass that to MacbethAnalyzer? These are issues thatrelated to the Dependency Inversion Principle aims to resolve.

What if XmlParser changes? What if we wanted to use a different kind of Parser? What if we wanted to construct a Fake object for testing and pass that to MacbethAnalyzer? These are issues that the Dependency Inversion Principle aims to resolve.

What if XmlParser changes? What if we wanted to use a different kind of Parser? What if we wanted to construct a Fake object for testing and pass that to MacbethAnalyzer? These are issues related to the Dependency Inversion Principle.

Add section on Dependency Inversion Principle
Source Link
jsuth
  • 857
  • 4
  • 17

Having completed a working implementation, I notice that ParserParser is only responsible for parsing Xml, which has a clear dependency in the constructor:

The given problem is small, but it's easy to imagine a larger project where we parse from several sources of varying formats beyond XML. It seems clear that the Parser classParser isn't specific enough and should be more meaningfully distinguished by renaming to XmlParserXmlParser.


Dependency Inversion Principle

The constructor of MacbethAnalzyer has tight coupling in the dependency to the low-level implementation details of XmlParser:

class MacbethAnalyzer
 @parser = XmlParser.new(MACBETH_URL)
 @speaker_line_counts = analyze_speaker_line_counts
 end

What if XmlParser changes? What if we wanted to use a different kind of Parser? What if we wanted to construct a Fake object for testing and pass that to MacbethAnalyzer? These are issues that the Dependency Inversion Principle aims to resolve.

The solution here is to use "dependency injection" to inject Parser into MacbethAnalyzer:

class MacbethAnalyzer
 attr_reader :speaker_line_counts
 MACBETH_URL = "http://www.ibiblio.org/xml/examples/shakespeare/macbeth.xml"
 IGNORE_SPEAKERS = %w(ALL)
 def initialize(parser)
 @parser = parser
 @speaker_line_counts = analyze_speaker_line_counts
 end
 def analyze_speaker_line_counts
 speaker_line_counts = Hash.new(0)
 speakers = parser.parse(query: '//SPEAKER')
 speakers.map do |speaker|
 unless IGNORE_SPEAKERS.include? speaker.text
 speaker_line_counts[speaker.text] += parser.parse(
 node: speaker, query: '../LINE').count
 end
 end
 speaker_line_counts
 end
 private
 attr_reader :parser
end
if __FILE__ == 0ドル
 analyzer = MacbethAnalyzer.new(XmlParser.new(MACBETH_URL))
 Printer.print_hash_val_capitalized_key(
 hash: analyzer.speaker_line_counts, filter: 'ALL')
end

Now MacbethAnalyzer doesn't depend on a lower-level implementation; we use duck typing to make things flexible, removing the dependency and resulting in much more loosely coupled code.

Having completed a working implementation, I notice that Parser is only responsible for parsing Xml, which has a clear dependency in the constructor:

The given problem is small, but it's easy to imagine a larger project where we parse from several sources of varying formats beyond XML. It seems clear that the Parser class isn't specific enough and should be more meaningfully distinguished by renaming to XmlParser.

Having completed a working implementation, I notice that Parser is only responsible for parsing Xml, which has a clear dependency in the constructor:

The given problem is small, but it's easy to imagine a larger project where we parse from several sources of varying formats beyond XML. It seems clear that classParser isn't specific enough and should be more meaningfully distinguished by renaming to XmlParser.


Dependency Inversion Principle

The constructor of MacbethAnalzyer has tight coupling in the dependency to the low-level implementation details of XmlParser:

class MacbethAnalyzer
 @parser = XmlParser.new(MACBETH_URL)
 @speaker_line_counts = analyze_speaker_line_counts
 end

What if XmlParser changes? What if we wanted to use a different kind of Parser? What if we wanted to construct a Fake object for testing and pass that to MacbethAnalyzer? These are issues that the Dependency Inversion Principle aims to resolve.

The solution here is to use "dependency injection" to inject Parser into MacbethAnalyzer:

class MacbethAnalyzer
 attr_reader :speaker_line_counts
 MACBETH_URL = "http://www.ibiblio.org/xml/examples/shakespeare/macbeth.xml"
 IGNORE_SPEAKERS = %w(ALL)
 def initialize(parser)
 @parser = parser
 @speaker_line_counts = analyze_speaker_line_counts
 end
 def analyze_speaker_line_counts
 speaker_line_counts = Hash.new(0)
 speakers = parser.parse(query: '//SPEAKER')
 speakers.map do |speaker|
 unless IGNORE_SPEAKERS.include? speaker.text
 speaker_line_counts[speaker.text] += parser.parse(
 node: speaker, query: '../LINE').count
 end
 end
 speaker_line_counts
 end
 private
 attr_reader :parser
end
if __FILE__ == 0ドル
 analyzer = MacbethAnalyzer.new(XmlParser.new(MACBETH_URL))
 Printer.print_hash_val_capitalized_key(
 hash: analyzer.speaker_line_counts, filter: 'ALL')
end

Now MacbethAnalyzer doesn't depend on a lower-level implementation; we use duck typing to make things flexible, removing the dependency and resulting in much more loosely coupled code.

Add section on improving class name to XmlParser
Source Link
jsuth
  • 857
  • 4
  • 17
Loading
Improve clarity
Source Link
jsuth
  • 857
  • 4
  • 17
Loading
Trim an ugly sentence.
Source Link
jsuth
  • 857
  • 4
  • 17
Loading
Improve sentence
Source Link
jsuth
  • 857
  • 4
  • 17
Loading
Source Link
jsuth
  • 857
  • 4
  • 17
Loading
default

AltStyle によって変換されたページ (->オリジナル) /