Ruby on rails 持久化复合模式实现——RubyonRails
有没有人有一个很好的端到端示例,说明如何将来自GoF的文本书复合模式持久化到数据库中,如下面的一个 组件基类:Ruby on rails 持久化复合模式实现——RubyonRails,ruby-on-rails,design-patterns,composite,Ruby On Rails,Design Patterns,Composite,有没有人有一个很好的端到端示例,说明如何将来自GoF的文本书复合模式持久化到数据库中,如下面的一个 组件基类: class Task attr_reader :name def initialize(name) @name = name end def get_time_required 0.0 end end 复合类: class CompositeTask < Task def initialize(name) super(name
class Task
attr_reader :name
def initialize(name)
@name = name
end
def get_time_required
0.0
end
end
复合类:
class CompositeTask < Task
def initialize(name)
super(name)
@sub_tasks = []
end
def add_sub_task(task)
@sub_tasks << task
end
def remove_sub_task(task)
@sub_tasks.delete(task)
end
def get_time_required
time = 0.0
@sub_tasks.each { |task| time += task.get_time_required }
time
end
end
类复合任务 @sub_tasks您只需要将属性持久化到db,例如name
和time
(您可能希望持久化它,而不是在运行时分配它)和sub_tasks
。您只对叶任务执行此操作。您通常不会将每个组合任务都持久化到数据库中
您可以使用STI(单表继承)来实现此模式。您可以创建一个基类任务
(假设Rails4)。然后,您可以从中为LeafTask
和compositetask
创建子类。然后,您可以将您拥有的每个任务作为其中任何一个任务的实例进行持久化。如果您的任务需要非常不同的接口,那么您可能希望对每个接口进行子类化。如果它们中的每一个都需要非常不同的属性,那么您可以考虑多表继承(即,它们仍然是从<代码>任务> /代码>的子类,但是它们使用它们自己的表)。迟到一年,但我觉得扩展我的答案仍然有用。每个任务都需要一个ID,假设这个ID是任务的名称。然后,通过任务中的新父属性,您将能够持久化组合的树结构:
class Task
attr_reader :name
attr_reader :parent
def initialize(name, parent=nil)
@name = name
@parent= parent
end
def get_time_required
0.0
end
end
通过这种方式,您将能够从父级导航到其子级select*from tasks where parent_id=?
或从某个子级导航到其父级select*from tasks where id=?
另一个技巧是使用索引,就像在章节中一样,检索某个节点下的所有层次结构。如果您有一个树\u code
字段,则可以通过以下方式保持:
- 根节点将有0个
树\u code
- root的子代将有1,2,3<代码>树\代码
(这些是第一代)
tree\u code
1的节点的第二代将具有1.1、1.2、<代码>树\代码。对于具有树的节点,代码2将具有2.1、2.2、<代码>树\代码
select*从任务中检索任务1的所有子节点,其中树的代码类似于'1.%'
这始终是插入/更新与选择之间的性能权衡,因为在持久化任何组件之前,您必须计算树\u code
如果您在Rails应用程序的上下文中,您可以随时使用谢谢。如何持久化CompositeTask创建的关系?