面试题答案
一键面试设计思路
- 组合模式:组合模式将对象组合成树形结构以表示“部分 - 整体”的层次结构。在树形结构数据处理中,每个节点(无论是叶子节点还是非叶子节点)都应该具有相似的接口,以便统一处理。
- 策略模式:策略模式定义一系列算法,将每个算法封装起来,并使它们可以相互替换。在树形结构处理中,不同的遍历策略(如深度优先遍历、广度优先遍历)可以用策略模式实现。
- 访问者模式:访问者模式将数据结构与数据操作分离。在树形结构中,对于不同类型的节点可能有不同的操作,使用访问者模式可以将这些操作封装在访问者类中,而不影响树形结构本身。
代码结构
- TreeNode类:表示树形结构中的节点,包含添加子节点、删除子节点等方法。
- Tree类:表示整个树形结构,包含根节点以及一些操作树形结构的方法。
- TraversalStrategy类:策略模式相关,定义遍历策略的接口。
- DepthFirstTraversal和BreadthFirstTraversal类:实现不同的遍历策略。
- Visitor类:访问者模式相关,定义访问节点的接口。
- ConcreteVisitor类:实现具体的访问操作。
关键代码片段
# 组合模式相关
class TreeNode
attr_accessor :name, :children
def initialize(name)
@name = name
@children = []
end
def add_child(child)
@children << child
end
def remove_child(child)
@children.delete(child)
end
def accept(visitor)
visitor.visit(self)
@children.each { |child| child.accept(visitor) }
end
end
class Tree
attr_accessor :root
def initialize(root)
@root = root
end
def traverse(strategy)
strategy.execute(root)
end
end
# 策略模式相关
class TraversalStrategy
def execute(node)
raise NotImplementedError
end
end
class DepthFirstTraversal < TraversalStrategy
def execute(node)
puts node.name
node.children.each { |child| execute(child) }
end
end
class BreadthFirstTraversal < TraversalStrategy
def execute(node)
queue = [node]
while queue.any?
current = queue.shift
puts current.name
queue += current.children
end
end
end
# 访问者模式相关
class Visitor
def visit(node)
raise NotImplementedError
end
end
class ConcreteVisitor < Visitor
def visit(node)
puts "Visiting #{node.name}"
end
end
结合使用示例
# 创建树形结构
root = TreeNode.new("Root")
child1 = TreeNode.new("Child1")
child2 = TreeNode.new("Child2")
root.add_child(child1)
root.add_child(child2)
tree = Tree.new(root)
# 使用策略模式遍历
depth_first = DepthFirstTraversal.new
tree.traverse(depth_first)
breadth_first = BreadthFirstTraversal.new
tree.traverse(breadth_first)
# 使用访问者模式
visitor = ConcreteVisitor.new
root.accept(visitor)
通过以上代码,我们基于组合模式构建了一个处理树形结构数据的通用框架,并展示了如何与策略模式、访问者模式结合以满足更复杂的业务需求。组合模式提供了树形结构的基本操作,策略模式封装了不同的遍历算法,访问者模式将节点操作与节点结构分离。