2015-10-16 3 views
0

Я столкнулся с различными сообщениями, в которых говорится, что использование instanceof не считается хорошей практикой.Использование instanceof operaator для десериализации

http://www.javapractices.com/topic/TopicAction.do?Id=31 https://www.artima.com/interfacedesign/PreferPoly.html

Я нахожусь в ситуации, когда у меня есть упорядоченный объект, который может быть 7,8 реальных типов. Сейчас я использую оператор insntanceof и проверяю с различными условиями if, является ли объект фактическим, а затем выполняет некоторые операции.

мой дизайн плохой?

Если да, то как решить эту проблему без использования instanceof?

Иерархия наследования отличается для каждого объекта, поэтому мне сложно заменить его полиморфизмом.

код

public String exportAsPMML(MLModel model) throws MLModelHandlerException { 
     Externalizable extModel = model.getModel(); 

     //Deserializing to find the actual type of the model 
     if (extModel instanceof MLClassificationModel) { 
      ClassificationModel clasModel = ((MLClassificationModel) extModel).getModel(); 
      if (clasModel instanceof LogisticRegressionModel) { 
       return ((LogisticRegressionModel) clasModel).toPMML(); 
      } else { 
       throw new MLModelHandlerException("PMML export not supported for model type"); 
      } 
     } else if (extModel instanceof MLGeneralizedLinearModel) { 
      GeneralizedLinearModel genModel = ((MLGeneralizedLinearModel) extModel).getModel(); 
      if (genModel instanceof LinearRegressionModel) { 
       return ((LinearRegressionModel) genModel).toPMML(); 
      } else if (genModel instanceof LassoModel) { 
       return ((LassoModel) genModel).toPMML(); 
      } else if (genModel instanceof RidgeRegressionModel) { 
       return ((RidgeRegressionModel) genModel).toPMML(); 
      } else { 
       throw new MLModelHandlerException("PMML export not supported for model type"); 
      } 
     } else if (extModel instanceof MLKMeansModel) { 
      KMeansModel kmeansModel = ((MLKMeansModel) extModel).getModel(); 
      return kmeansModel.toPMML(); 
     } else { 
      throw new MLModelHandlerException("PMML export not supported for model type"); 
     } 
    } 
+1

Можете ли вы разместить свой код, где вы использовали 'instanceof'? – Rehman

+0

Вы можете сохранить этот тип как член – user

+0

Его трудно получить четкое изображение без фактического кода. Но в зависимости от вашего дизайна instanceof может быть допустимым решением. Вы могли бы также разработать с помощью генериков – Phuthib

ответ

3

Используйте существующий интерфейс PMMLExportable

GeneralizedLinearModel genModel = ((MLGeneralizedLinearModel) extModel).getModel(); 
if (genModel instanceof PMMLExportable) { 
    return ((PMMLExportable) genModel).toPMML(); 
} else { 
    throw new MLModelHandlerException("PMML export not supported for model type"); 
} 

Затем добавить свой собственный интерфейс, чтобы получить это:

public interface PpmlModelContainer{ 
    PMMLExportable getPMMLExportable(); 
} 

public String exportAsPMML(MLModel model) throws MLModelHandlerException { 
    Externalizable extModel = model.getModel(); 

    if (extModel instanceof PpmlModelContainer) { 
     PMMLExportable ppmlModel = ((PpmlModelContainer) extModel).getPMMLExportable(); 
     return ppmlModel.toPMML(); 
    } else { 
     throw new MLModelHandlerException("PMML export not supported for model type"); 
    } 
} 

Что необходимо осуществить то, что:

MLClassificationModel implements PpmlModelContainer 
MLGeneralizedLinearModel implements PpmlModelContainer 
MLKMeansModel implements PpmlModelContainer 

Система в настоящее время open closed. Открыто для расширения, закрыто для модификации.

+0

, но kmeansModel и LogisticRegressionModel не расширяет GeneralizedLinearModel – DesirePRG

+0

ОК, я добавил параметр интерфейса и расширил его до всей вашей проблемы. – weston

+0

Проблема LogisticRegressionModel, LinearRegressionModel и т. Д. От искры MLlib, и я должен реализовать это без изменения искровых внутренних компонентов. – DesirePRG

1

Хотя использование instanceof считается запахом кода, это не всегда так. В случаях, когда вам определенно нужно знать тип объекта, прежде чем что-либо делать, instanceof - хороший вариант.

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

В вашем случае кажется, что у вас может быть базовый интерфейс, имеющий метод toPMML, который может быть реализован всеми конкретными классами. Это на самом деле то, что мы подразумеваем под Program to interface.

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