Как обрабатывать различные реализации интерфейса с использованием шаблона MVP? - PullRequest
0 голосов
/ 29 января 2019

У меня есть проект, над которым я работаю, и я хотел уточнить, как следует обрабатывать несколько реализаций интерфейса, используя шаблон MVP.Вот моя ситуация:

Существует базовый интерфейс «Танк», который определяет основные функции того, что должен делать танк.

public interface ITankView
{
  public string TankName
  public double TankLevel
  public double TankSize
  ... ext ...
}

Мой докладчик принимает реализации этого интерфейса (т. Е. Представление «Танк»):

public class TankPresenter
{
  ITankView tank;
  public void TankPresenter(ITankView tank)
  {
    this.tank = tank;
  }

  public void DoStuffWithaBasicTank()
  {
     tank.TankName = "This is a basic Tank!"
     tank.TankSize = 100;
     tank.TankLevel = 50;
  }
}

У меня также есть несколько реализаций интерфейса ITankView:

// Just a basic tank with a level:
public class BasicTankView, ITankView
{
   public string TankName {get; set;}
   public double TankLevel {get; set;}
   public double TankSize {get; set;}
}

// The "Advanced" version of a tank:
public class MixableTankView, ITankView
{
   public double TankName {get; set;}
   public double TankLevel {get; set;}
   public double TankSize {get; set;}
   public double MixingSpeed {get; set;}
}

Итак, мой вопрос заключается в том, как мне обработать «Advanced» MixingTankView в TankPresenter, придерживаясь паттерна MVP и передового опыта?

Например, если бы я создал экземпляр TankPresenter с MixingTankView, как бы вы получили доступ к специальной «расширенной» функциональности?

public MixingTankView view = new MixingTankView();
public TankPresenter Presenter = new TankPresenter(view );


public class TankPresenter
{
  ITankView tank;
  public void TankPresenter(ITankView tank)
  {
    this.tank = tank;
  }

  public void DoStuffWithaMixingTank()
  {
     tank.TankName = "This is a mixing Tank!"
     tank.TankSize = 100;
     tank.TankLevel = 50;
     tank.MixingSpeed = 75; // This does not work as it's not declared in ITankView!!
  } 
}

Я думаю, мне нужно добавить докладчика для каждого танка.Так что в этом примере это были бы IBasicTankPresenter и IMixingTankPresenter, но я все еще немного запутался, как это будет работать.Также 90% функциональности между двумя резервуарами идентичны, поэтому они кажутся избыточными.На самом деле у меня больше, чем 2 танка, и фактическая реализация намного сложнее, но у каждого типа танка есть только небольшие различия.

Моими целями являются:

  1. Чтобы уменьшить сложность кода и взаимосвязь / взаимозависимость кода
  2. В некоторой степени придерживаться шаблона MVP
  3. Не повторяюсь кучу раз с каждым типом танка.
    • Я бы хотел уменьшить количество кода для моего собственного здравомыслия
    • Действительно ли мне нужен 1 ведущий для каждого 1 просмотра танка?

1 Ответ

0 голосов
/ 29 января 2019

Сначала вам нужно будет добавить интерфейс для MixableTankView -

public interface IMixableTankView : ITankView
{
    double MixingSpeed {get;set;}
}

Затем вы можете просто использовать дженерики.Вы начинаете с базового докладчика, только теперь вы меняете ITankView на параметр типа:

public class TankPresenter<TTankView> where TTankView : ITankView
{
    TTankView tank;
    // basic implementation here
}

и добавляете другого докладчика, который его наследует:

public class MixingTankPresenter : TankPresenter<IMixableTankView>
{
    // IMixableTankView special implementation here
}

Вы делаете это длякаждая другая реализация ITankView - таким образом, большая часть кода будет по-прежнему только в базовой TankPresenter, и вы сможете придерживаться принципов MVP на протяжении всего проекта.

...