Concrete Class vs Abstract Messages
In this chapter, you will learn about depending on abstract messages instead of concrete classes to write re-usable code.
Steps
Step 1
Create copy.rb
:
while line = gets
puts line
end
Step 2
Run it.
$ruby copy.rb
Here is a sample run:
Hi
Hi
Hello
Hello
Press Ctrl+D to quit the program. This reads from keyboard and writes to the console.
Step 3
Create a readme.txt
file:
This is the first line
This is the second line
Now run the program as follows:
$ruby copy.rb readme.txt
This reads the readme.txt
from the file and writes it to the console.
Step 4
Create file_copy.rb
:
File.open('./readme.txt', 'r') do |file|
while line = file.gets
puts line
end
end
Run it.
$ruby file_copy.rb
This reads the readme.txt
and writes it to the console.
Step 5
Create abstract.rb
with:
require 'stringio'
ip = StringIO.new('This is a test')
op = StringIO.new('', 'w')
ip.each_line do |line|
op.puts line
end
print op.string
This program uses StringIO a fake file system to read and write. This is good for testing. The dependency is on the message: each_line and puts and not on any concrete class. If there is a name of the class in the code, it creates tight coupling in the code and makes it difficult to reuse. As long as the ip and op variables can respond to the each_line and puts messages. This program will work.
Depend on messages that capture abstractions which can be varied by having different implementations.
Summary
In this chapter, we saw examples for:
Standard In --> Standard Out
Keyboard --> Console
File --> Console
Fake File --> Fake Console
You learned that depending on a concrete class creates tight coupling and depending on messages that can be implemented by different implementations in different class can lead to re-usable code.