I am reading "Design Patterns with Ruby" to improve the design ability of the program, and I will summarize the design patterns that interest me one by one.
This time, I summarized the template method pattern.
It is a pattern that describes the invariant part in the base class and encapsulates the changed part in the method defined in the subclass.
It is based on the design idea of separating what changes and what does not.
I will write a sample code after my hobby, muscle training. Both the bench press and the chin-up have the same training flow, but the specific flow is different.
Therefore, write a program that outputs the contents of each training.
class Training
def initialize(type)
@type = type
end
def start
prepare
execute
cleanup
end
def prepare
if @type == :bench_press
puts 'Start the bench press'
puts 'Set the barbell'
elsif @type == :tinning
puts 'Start pull-ups'
puts 'Get on the springboard'
end
end
def execute
puts 'Train'
end
def cleanup
puts 'Rubbing alcohol'
if @type == :bench_press
puts 'Return the barbell'
elsif @type == :tinning
puts 'Get off the platform'
end
end
end
At the time of calling, pass the training type as an argument. The execution result is as follows.
bench_press = Training.new(:bench_press)
bench_press.start
#Start the bench press
#Set the barbell
#Train
#Rubbing alcohol
#Return the barbell
tinning = Training.new(:tinning)
tinning.start
#Start pull-ups
#Get on the springboard
#Train
#Rubbing alcohol
#Get off the platform
Branching by if minutes by instance variable @type. It would be nice to have two types of training, but as the number of trainings increases, this conditional branch increases, making one method long and complicated.
Next, when rewriting by applying the Template Method pattern.
class Training
def start
prepare
execute
cleanup
end
def prepare
end
def execute
puts 'Train'
end
def cleanup
puts 'Rubbing alcohol'
end
end
class BenchPress < Training
def prepare
puts 'Start the bench press'
puts 'Set the barbell'
end
def cleanup
puts 'Return the barbell'
super
end
end
class Tinning < Training
def prepare
puts 'Start pull-ups'
puts 'Get on the springboard'
end
def cleanup
super
puts 'Get off the platform'
end
end
At the time of calling, an instance of the subclass is created, and before applying the template method pattern, the training item was passed as an argument, but that is gone. The execution result is as follows.
bench_press = BenchPress.new
bench_press.start
#Start the bench press
#Set the barbell
#Train
#Rubbing alcohol
#Return the barbell
tinning = Tinning.new
tinning.start
#Start pull-ups
#Get on the springboard
#Train
#Rubbing alcohol
#Get off the platform
Only the outline of training is defined in the base class Training, and the specific training content is defined in the subclass.
When I needed to create a new subclass, I only had to change the subclass without changing the base class, which made it more resistant to change.
The template method pattern was an object-oriented design pattern using inheritance.
Personally, I think that it is the most frequently used design pattern, so I want to be able to master it.
Recommended Posts