使用instanceof操作符进行反序列化

时间:2015-10-16 08:39:01

标签: java instanceof

我遇到过不同的帖子,说使用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");
        }
    }

2 个答案:

答案 0 :(得分: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。打开扩展,关闭修改。

答案 1 :(得分:1)

虽然假设使用instanceof是代码气味,但事实并非如此。如果您在做任何事情之前肯定需要知道对象的类型,那么instanceof是一个不错的选择。

但是有很多很多,并根据类型(使用强制转换)调用单独的方法不是一个好选择。在这种情况下,我们需要重新考虑层次结构和可能的重构。

在您的情况下,您似乎可以拥有一个方法toPMML的基接口,可以由所有具体类实现。这实际上是Program to interface的意思。