2016-01-20 99 views
0

例如,我有两个类如何避免嵌套开关结构?

public class A 
{ 
    public Guid Id { get; set;} 
    public string Type { get; set; } 
    public string State { get; set; } 
    public string SomeProperty { get; set; } 
} 

public class B 
{ 
    public Guid Id { get; set; } 
    public string Type { get; set; } 
    public string State { get; set; } 
    public string AnotherProperty { get; set; } 
} 

每个班级都有自己的仓库

public class RepA 
{ 
    public void Add(A entity) 
    { 
     // some specific logic here 
    } 

    public void Delete(A entity) 
    { 
     // some specific logic here 
    } 
} 

public class RepB 
{ 
    public void Add(B entity) 
    { 
     // some specific logic here 
    } 

    public void Delete(B entity) 
    { 
     // some specific logic here 
    } 
} 

我需要实现节能与动态类型的实体列表的方法。我想避免使用嵌套的“开关”结构(如下所列),因为我有两种以上的状态和两种以上的状态,代码会变得杂乱无章。

private readonly RepA _repA = new RepA(); 
private readonly RepB _repB = new RepB(); 

public void SaveChanges(List<dynamic> entities) 
{ 
     foreach (var entity in entities) 
     { 
      switch (entity.Type) 
      { 
       case "A": 
        var a = entity as A; 
        switch (entity.State) 
        { 
          case "Added": 
           _repA.Add(a); 
           break; 
          case "Deleted": 
           _repA.Delete(a); 
           break; 
        } 
        break; 
       case "B": 
        var b = entity as B; 
        switch (entity.State) 
        { 
          case "Added": 
           _repB.Add(b); 
           break; 
          case "Deleted": 
           _repB.Delete(b); 
           break; 
        } 
        break; 
      } 
     } 
} 

您能否提出其他解决方案? 我想过基类和基础知识库的接口。但在这种情况下,何时以及如何初始化依赖于实体类型的_repo?

private IBaseRep _repo; 

public void SaveChanges(List<dynamic> entities) 
{ 
     foreach (var entity in entities) 
     { 
      switch (entity.State) 
      { 
       case "Added": 
        _repo.Add(entity) 
        break; 
       case "Deleted": 
        _repo.Delete(entity) 
        break; 
      } 
     } 
} 
+0

'case'Deleted“:_repB.Add(b);'一个错误?你的意思是'_repB.Delete(b);'? –

+1

首先为什么需要成为'List '?还有其他更好的选项,比如界面和抽象类。 –

+0

这取决于A和B在域上下文中的含义?他们是相关的还是可以参与继承?我想是的,看着他们的成员。请确认。 – niksofteng

回答

0

您的实体类AB违反DRY原则。下面怎么样?我能想到的一个问题是实体集合的多重枚举,但我不确定这个集合有多大才能知道这是否是真正的问题。

public abstract class Entity 
{ 
    public Guid Id { get; set; } 
    public string Type { get; set; } 
    public string State { get; set; } 
} 

public class A : Entity 
{ 
    public string SomeProperty { get; set; } 
} 

public class B : Entity 
{ 
    public string AnotherProperty { get; set; } 
} 

public abstract class Rep<T> where T : Entity 
{ 
    public abstract void Add(T entity); 
    public abstract void Delete(T entity); 
    public virtual void SaveChanges(IEnumerable<T> entities) 
    { 
     foreach (var entity in entities) 
     { 
      switch (entity.State) 
      { 
       case "Added": 
        Add(entity); 
        break; 
       case "Deleted": 
        Delete(entity); 
        break; 
       default: 
        throw new InvalidOperationException($"Invalid entity state {entity.State}"); 
      } 
     } 
    } 
} 

public class RepA : Rep<A> 
{ 
    public override void Add(A entity) 
    { 
     // some specific logic here 
    } 

    public override void Delete(A entity) 
    { 
     // some specific logic here 
    } 
} 

public class RepB : Rep<B> 
{ 
    public override void Add(B entity) 
    { 
     // some specific logic here 
    } 

    public override void Delete(B entity) 
    { 
     // some specific logic here 
    } 
} 

public class Program 
{ 
    private static readonly RepA _repA = new RepA(); 
    private static readonly RepB _repB = new RepB(); 

    public static void Main() 
    { 
     var entities = new List<Entity>(); 

     // fill the list here 

     _repA.SaveChanges(entities.OfType<A>()); 
     _repB.SaveChanges(entities.OfType<B>()); 
    } 
} 
+0

感谢您的回答。 那么A类的SomeProperty和B类的AnotherProperty怎么样,在这种情况下不会错过? –

+0

不可以。属性应该属于每个类。此外,您可以在“RepA”类和“RepB”的“Add()”和“Delete()”方法中根据“SomeProperty”和“AnotherProperty”实现逻辑。 – WiSeeker

+0

谢谢。我会尝试 –