Как избежать instanceof при сокрытии поля - PullRequest
0 голосов
/ 17 мая 2019

Я начну с того, что прочитал довольно много вопросов, которые задают о том, как избегать instanceof, но я не смог найти ни одного, который бы полностью отвечал требованиям того, что мы видим. Пожалуйста, дайте мне знать, если вы видите что-либо, касающееся этой конкретной точки, хотя!

Есть проблема, с которой мы сталкиваемся сейчас, когда у нас есть класс, который отвечает за хранение информации о действиях, которые необходимо предпринять в определенное время. Эти времена могут быть одного действия или повторяться в течение некоторого периода. У нас есть одно поле (продолжительность действия), которое действительно только для повторяющихся действий. Изначально у нас был Enum для типа времени и отдельное поле для длительности в составе одного класса.

class Action {
    long duration;
    Enum timeType;
}

Изменить на:

class Action {
    TimeTypeStrategy timeTypeStrategy;
}

class RecurringTimeTypeStrategy extends TimeTypeStrategy {
    long duration
}

class SingleTimeTypeStrategy extend TimeTypeStrategy {
}

abstract class TimeTypeStrategy {
}

Таким образом, с этим измененным кодом мы можем по существу сказать, что мы можем иметь только один или другой тип, и что длительность может быть только свойством повторяющегося типа времени. Однако это также означает, что всякий раз, когда мы хотим, чтобы действие (или другие классы, которые используют действие) обрабатывали его на основе его повторяющегося типа времени, оно должно вызывать instanceof в поле timeTypeStrategy для фактического получения продолжительности и выполнения любого планирования, в котором оно нуждается.

Одна мысль заключалась в том, что усилия по определению того, что значит быть конкретным типом времени, могут быть включены в саму стратегию. Такое ощущение, что оно должно основываться только на названии, но это требует значительного изменения некоторого кода планирования и в конечном итоге нарушает некоторые из парадигм, которые были разработаны при разработке этих расписаний. Может быть, это то решение, которое нам нужно, но такое ощущение, что оно не должно быть единственным.

Что касается шаблонов проектирования, есть ли лучший метод, который не приводит к запаху экземпляра кода, который позволяет вызывающей стороне решать, что делать на основе этих полей?

1 Ответ

1 голос
/ 18 мая 2019

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

abstract class Action {
   Enum timeType;
   abstract void Accept(IVisitor visitor);
}
class SingleAction extends Action {

   override void Accept(IVisitor visitor) {
      visitor.Visit(this);
  }
}
class RepeatedAction extends Action {
   long duration;

   override void Accept(IVisitor visitor) {
      visitor.Visit(this);
  }
}

Тогда вы можете иметь интерфейс посетителя:

interface IVisitor {
  void Visit(SingleAction action);
  void Visit(RepeatedAction action);
}

и реализацию посетителя:

class ActionVisitor implements IVisitor {

  void Visit(SingleAction action) {
    // Execute the action
  }

  void Visit(RepeatedAction action) {
    // Here you can access action.duration and schedule the action
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...