У меня есть следующие конкретные классы, которые реализуют общий интерфейс
EvaluatorA : IEvaluator
EvaluatorB : IEvaluator
EvaluatorC : IEvaluator
Интерфейс IEvaluator
имеет только одну функцию - Evaluate
, которая реализована во всех трех типах вычислителей. И у меня есть класс драйвера, который вызывает оценщик на основе конфигурации, однако он имеет доступ (по дизайну) только к IEvalutor
, т. е. ему не нужно знать, какой конкретный оценщик вызывается в данный момент.
Проблема возникает, когда одному из оценщиков, скажем EvaluatorC
, нужно реализовать новую функцию Predict
, а мое требование касается только EvaluatorC
, функцию Predict
нужно вызывать после вызова Evaluate
.
Временное решение 1. Одним из решений является проверка типа оценщика:
// evaluator is previously instanciated
evaluator.Evaluate();
if (evaluator is EvaluatorC)
evaluator.Predict();
Как видите, это не аккуратно. Скажем, завтра мне нужно вызвать другую функцию Dance
только для EvaluatorB
и функцию Sing
для обоих EvaluatorA
и EvaluatorB
, это становится беспорядочным.
Временное решение 2. Добавьте функцию Predict
в интерфейс IEvaluator
, а для других оценщиков просто реализуйте функцию с пустым телом. Это может работать для функций с типом возврата void
, но требуется дополнительная проверка безопасности в программе драйвера, если тип возврата не void
. Кроме того, я не уверен, что функция с пустым телом только в качестве заполнителей является хорошей идеей или нет.
Временное решение 3. Измените интерфейс на абстрактный класс. Это похоже на решение 2, но обеспечивает реализацию по умолчанию Predict
. Однако этот подход мне тоже не понравился, так как он изменяет первоначальную структуру проекта и не дает много преимуществ по сравнению с решением 2.
В общем, у меня нет удовлетворительного решения этой проблемы. Я надеюсь, что decoration pattern
может помочь (но я не уверен). Эта проблема не специфична для каких-либо языков программирования. Пожалуйста, прыгайте и делитесь своими идеями.
Правка 1: добавлены некоторые сведения об обязанностях оценщика. Предполагается, что оценщики оценивают данное решение и возвращают некоторые показатели. После получения оценочных показателей программа-драйвер выполнит некоторые служебные задачи, такие как составление отчетов, обратите внимание, что это необходимо для всех оценщиков. Затем одному из оценщиков (EvaluatorC
) нужно вызвать Predict()
на основе сгенерированных отчетов. Однако другим оценщикам этот шаг не требуется.
Predict
в методеEvaluate
EvaluatorC
? - person sdgfsdh   schedule 03.10.2017Evaluate()
в программе-драйвере необходимо выполнить некоторую вспомогательную работу.Predict()
можно вызывать только после этого. - person Lin   schedule 03.10.2017Evaluate
? Похоже, вы еще не нашли подходящую абстракцию для своей задачи. - person sdgfsdh   schedule 03.10.2017Evaluate
иPredict
. Похоже, чтоPredict
не является обычным явлением дляEvaluator
, поэтому его просто не должно быть внутри этого класса. Вы можете переместить его в другой классPredictor
, который вы будете использовать внутри своего классаdriver
после вызоваevaluate
. Predictor может получить ответ отEvaluator
и сделать свое дело. - person Alex Buyny   schedule 03.10.2017