使用 instanceof 运算符进行反序列化
Using instanceof operarator for deserialization
我看到过不同的帖子,它们说使用 instanceof 被认为不是一个好的做法。
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");
}
}
使用现有界面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。对扩展开放,对修改关闭。
虽然使用 instanceof
被认为是一种代码味道,但情况并非总是如此。如果您在做任何事情之前肯定需要知道对象的类型,那么 instanceof
是一个不错的选择。
但是拥有大量的方法并根据类型调用单独的方法(使用转换)并不是一个好的选择。在那种情况下,我们需要重新考虑层次结构和可能的重构。
在您的情况下,您似乎可以拥有一个具有方法 toPMML
的基本接口,它可以由所有具体 类 实现。这实际上就是我们所说的 Program to interface
.
我看到过不同的帖子,它们说使用 instanceof 被认为不是一个好的做法。
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");
}
}
使用现有界面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。对扩展开放,对修改关闭。
虽然使用 instanceof
被认为是一种代码味道,但情况并非总是如此。如果您在做任何事情之前肯定需要知道对象的类型,那么 instanceof
是一个不错的选择。
但是拥有大量的方法并根据类型调用单独的方法(使用转换)并不是一个好的选择。在那种情况下,我们需要重新考虑层次结构和可能的重构。
在您的情况下,您似乎可以拥有一个具有方法 toPMML
的基本接口,它可以由所有具体 类 实现。这实际上就是我们所说的 Program to interface
.