【问题标题】:Preferred way to "move" an object between lists在列表之间“移动”对象的首选方式
【发布时间】:2009-07-23 20:01:00
【问题描述】:

我有两个单独的实体列表:

class EntityCollection : IList<Entity>
{
    //...
}

EntityCollection Foo;
EntityCollection Bar;

我想实现一个操作,将列表 Foo 中的对象 Qux 移动到 Bar。最好的实现方式是什么?

  • 作为EntityCollection 上的MoveTo 实例方法:

    public void MoveTo(EntityCollection to, Entity entity);
    
    // Client code
    Foo.MoveTo(Bar, Qux);
    
  • 作为EntityCollection 上的MoveFrom 实例方法:

    public void MoveFrom(EntityCollection from, Entity entity);
    
    // Client code
    Bar.MoveFrom(Foo, Qux);
    
  • 作为EntityCollection 上的静态Move 方法:

    public static void Move(Entity entity, EntityCollection from, EntityCollection to);
    
    // Client code
    EntityCollection.Move(Qux, Foo, Bar);
    
  • 作为包含两个集合的类的Move 实例方法:

    public void Move(Entity entity, EntityCollection from, EntityCollection to);
    
    // Client code
    Holder.Move(Qux, Foo, Bar);
    

或者,由于实体一次只能在一个集合中,我可以让实体自己跟踪它们的位置,并在实体本身上实现它:

    public void MoveTo(EntityCollection to)
    {
       if(Location != null)
           Location.Remove(this);
       to.Add(this);
       Location = to;
    }

    // Client code
    Entity e;
    e.MoveTo(Foo);

    // Later on...
    e.MoveTo(Bar);

当出现这么多选项时,我想知道:move 方法属于哪里?为什么?

【问题讨论】:

    标签: list methods separation-of-concerns


    【解决方案1】:

    最终,我认为这并不重要,所以我的温和回答是不要担心。

    从语言上讲,MoveTo 似乎比 MoveFrom 更自然——尽管我可以想象为了完整性而实现两者。

    从概念上讲,在我看来,集合实例和被移动的实体都不是对移动“负责”的,这可能会让我倾向于把它作为一种静态方法——否则你会赋予其中一个额外的重要性三件事在运作。

    构建一个 Holder 来完成这个动作似乎有点过分了。

    但这真的取决于你,更多地了解这些东西通常是如何被消费的,可能会知道什么是“正确”的解决方案。

    【讨论】:

    • 我问的原因不是语言,而是责任。感谢您的意见。顺便说一句,Holder 已经存在,我只会为其添加功能。
    • 我一直在详细介绍系统的其他部分,我得出的结论应该是 Holder 进行了移动,因为它还会执行一些验证,因为某些实体无法移动到 Bar。
    【解决方案2】:

    MoveTo 和 MoveFrom 都将使用对 Add() 和 Remove() 的调用,因此您可以在一个函数中执行这两个操作。在这种情况下,您可以执行以下操作:

    enum MoveDirection
    {
        ToFoo = 0
        ToBar = 1
    }
    
    MoveItem(Entity entity, MoveDirection direction)
    {
        if direction = 0
           //move entity from Bar to Foo
        elseif direction = 1
           //move entity from Foo to Bar
        endif
    }
    

    【讨论】:

    • 我认为他的意思是把它放在包含两个集合的类中,像这样:Holder.MoveItem(Foo, ToBar)。
    • Holder.MoveItem(Foo, MoveDirection.ToBar),我的意思是
    • @Martinho,正确。很抱歉遗漏了我的答案的客户端代码部分。任何持有这两个集合(Foo 和 Bar)的类都会有 MoveItem 定义。
    • 我想我会选择那个选项,或者把它放在实体中。
    【解决方案3】:

    使用扩展方法怎么样?

    客户端代码是:

    Foo.Move(Qux).To(Bar);
    

    签名:

    public static Entity Move(this EntityCollection from, Entity entity)
    public static void To(this Entity entity, EntityCollection to)
    

    Fluent!

    【讨论】:

    • 所以你基本上是在调用删除“移动”并添加“到”。我喜欢它在这种情况下的外观,但我不寒而栗地想到单独使用 Move() 或 To() 的代码会喜欢阅读。
    • 我不喜欢这个,因为我希望它是一个单一的操作。看到这个我的第一个想法和 Darth Eru 的完全一样:如果我写 Foo.Move(Qux) 会怎样?不过看起来确实不错。
    • 也许 Move 可以返回一些包含实体和源的部分命令对象(请参阅 GoF),而不是实体。我认为这样会更好,因为只有 To 会实际做某事,而不是拆分操作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-02
    • 1970-01-01
    相关资源
    最近更新 更多