用多态替换条件 - 它是如何工作的?

时间:2017-05-02 15:52:59

标签: oop refactoring

我经常听到“试着避免if / switch结构。如果你有它们,那么将它们重构为子类” 我没有意识到这件事是如何起作用的。 好的,你的代码中有if / switch。然后你创建了几个新类。但是要决定使用哪个类,您需要在Fabric类(生成这些对象的位置)中实现switch。我错了吗?

P.S。对不起我的英语不好。我是读者,不是作家。

1 个答案:

答案 0 :(得分:2)

  

但是要确定你将使用哪个类,你需要实现switch if   在fabric类中(生成这些对象的位置)。我错了吗?

不,你没错。虽然开关上的多态性是一件好事,但也有例外。一个这样的例外是你有参数化工厂,这是绝对可以接受的。因此,不是您的客户端代码根据条件创建专门的类,您将要求此工厂为您创建它们。优点是Factory将负责创建这些类实例,如果引入新类,则只修改工厂而不是客户端代码。

所以不要这样:

public class Client {
    public string Serialize<T>(string contentType, T instance) where T : class {
        switch(contentType) {
            case "XML":
                return new XMLSerializer().Serialize(instance);
            case "JSON":
                return new JSONSerializer().Serialize(instance);
        }
    }
}

你将拥有:

public interface ISerializer {
    string Serialize(object instance);
    object Deserialize(string content);
}

public class XMLSerializer : ISerializer { }
public class JSONSerializer : ISerializer { }

public class SerializerFactory() {
    public static ISerializer CreateSerializer(string type) {
        switch(type) {
            case "XML":
                return new XMLSerializer();
            case "JSON":
                return new JSONSerializer();
        }
    }
}

public class Client {
    public string ParseAPIResponse(string contentType, string responseData) {
        ISerializer serializer = SerializerFactory.CreateSerializer(contentType);
        var responseObj = serializer.Deserialize(responseData);
    }
}

请注意,Factory的更改只有一个原因,那就是引入新的Serializer,所以我们在这里很好用SRP。更进一步,有一些方法可以避免修改工厂,使用配置文件存储标识符类型映射或简单地在工厂公开另一个方法,以允许其用户注册新类型等。这就在你身上。