2016-01-20 2 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

Is 'case" Deleted ": _repB.Add (b);' ошибка? Вы имели в виду '_repB.Delete (b);'? –

+1

Прежде всего, почему это должно быть «Список '? Существуют и другие варианты, такие как интерфейс и абстрактные классы. –

+0

Это зависит от того, что A и B находятся в контексте домена? Связаны ли они или могут участвовать в наследовании? Я думаю, да, глядя на их членов. Пожалуйста подтвердите. – niksofteng

ответ

0

Ваши объектные классы A и B бросает вызов 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

Спасибо за ваш ответ. Что относительно SomeProperty от класса A и AnotherProperty от класса B, разве они не будут пропущены в этом случае? –

+0

№ Свойства по праву принадлежат каждому классу. Кроме того, вы можете реализовать логику в зависимости от 'SomeProperty' и' AnotherProperty' в классах 'RepA' и' RepB' 'методы Add()' и 'Delete()'. – WiSeeker

+0

Спасибо. Я попробую –

Смежные вопросы