
代码示例:
以下是两个在 Ruby 中使用模板方法模式的详细实例:
实例一:文档生成系统
假设我们需要开发一个文档生成系统,用于生成不同格式的文档,如 HTML 和 Markdown。这些文档的生成过程有共同的步骤,但具体的实现细节因格式而异。模板方法模式可以很好地解决这个问题。
抽象类
class DocumentGenerator
def generate
prepare_data
create_document
save_document
end
def prepare_data
puts "Preparing data..."
end
def create_document
raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
end
def save_document
puts "Saving document..."
end
end
generate是模板方法,定义了文档生成的步骤,包括准备数据、创建文档和保存文档。prepare_data和save_document是具体实现,适用于所有子类。create_document是抽象方法,需要在子类中实现,因为不同格式的文档创建方式不同。
子类:HTML 文档生成器
class HtmlDocumentGenerator < DocumentGenerator
def create_document
puts "Creating HTML document..."
end
end
- 重写了
create_document方法,实现 HTML 文档的创建逻辑。
子类:Markdown 文档生成器
class MarkdownDocumentGenerator < DocumentGenerator
def create_document
puts "Creating Markdown document..."
end
end
- 重写了
create_document方法,实现 Markdown 文档的创建逻辑。
客户端代码
html_generator = HtmlDocumentGenerator.new
html_generator.generate
markdown_generator = MarkdownDocumentGenerator.new
markdown_generator.generate
- 客户端代码通过调用
generate方法,使用不同的子类生成不同格式的文档,而无需关心具体的实现细节。
实例二:咖啡店饮品制作
假设咖啡店有多种饮品,如咖啡和茶,它们的制作过程有共同的步骤,但具体的实现细节因饮品而异。模板方法模式可以很好地解决这个问题。
抽象类
class Beverage
def prepare
boil_water
brew
pour_in_cup
add_condiments
end
def boil_water
puts "Boiling water..."
end
def brew
raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
end
def pour_in_cup
puts "Pouring into cup..."
end
def add_condiments
raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
end
end
prepare是模板方法,定义了饮品制作的步骤,包括烧水、冲泡、倒入杯子和添加调料。boil_water和pour_in_cup是具体实现,适用于所有子类。brew和add_condiments是抽象方法,需要在子类中实现,因为不同饮品的冲泡和添加调料方式不同。
子类:咖啡
class Coffee < Beverage
def brew
puts "Dripping coffee through filter..."
end
def add_condiments
puts "Adding sugar and milk..."
end
end
- 重写了
brew和add_condiments方法,实现咖啡的冲泡和添加调料逻辑。
子类:茶
class Tea < Beverage
def brew
puts "Steeping the tea..."
end
def add_condiments
puts "Adding lemon..."
end
end
- 重写了
brew和add_condiments方法,实现茶的冲泡和添加调料逻辑。
客户端代码
coffee = Coffee.new
coffee.prepare
tea = Tea.new
tea.prepare
- 客户端代码通过调用
prepare方法,使用不同的子类制作不同的饮品,而无需关心具体的实现细节。
这两个实例展示了模板方法模式在 Ruby 中的应用,通过定义一个抽象类中的模板方法,将算法的骨架固定下来,同时将具体的实现细节留给子类去完成,从而实现了代码的复用和扩展。
更多技术文章见公众号: 大城市小农民

741

被折叠的 条评论
为什么被折叠?



