设计模式
举个例子,比如我们有个导出功能,按照不同的格式导出数据,比如 CSV、Excel、JSON 等;比如我们需要导入execl文件,需要解析文件内容,针对不同的格式,需要不同的解析方式;再比如我们有一个给用户发送邮件功能,有可能需要用 gmail, qq, 163 等邮箱服务商,手机验证码服务也是如此。如果我们使用 if-else 或者 switch-case 来实现,代码会变得很臃肿,而且扩展性很差,多一个导出为其他格式的需求,就需要大量修改代码。
处理之前的代码可能长这样:
策略模式
策略模式的主要作用是用来提升一些代码的复用性的,或者解决代码中出现很多 if-else 语句的问题。
那么利用策略模式进行优化呢,则是一种利用添加大量相关类的方式,通过 OOP 的继承和组合的方式,来减少调用时的 if-else 语句,提高代码的可扩展性,同时维护可读性和简洁性。
模板方法模式
由于上一种优化把具体的导出逻辑都封装在出来了,一定程度上提升了代码可扩展性,但是在添加新的导出格式时,仍然需要动这个 Map。同时,代码的复用性其实仍然没有提升,只是把 if-else 语句封装成了一个类。
接下来我们可以用模板方式来解决,具体地,我们可以使用一个抽象类作为中间层,放在接口类 Exporter 和实现类 CSVExporter、ExcelExporter 之间,来简化重复的代码,以提升代码复用性。
工厂模式
那么现在我们解决了代码复用性不高,也就是重复代码过多的问题。但扩展代码时,需要在静态 map 中添加新类型的问题依旧存在,因为我们始终需要通过 String 类型的 type 参数来获取执行的具体的 Exporter 对象。
我们很容易可以想到可以利用工厂模式来解决,工厂模式生来就是为了 创建对象,并且根据 参数的不同,返回 不同的对象,这恰好符合了我们的需求。
具体地,我们多创建一个枚举类,用来映射导出格式名和对应的 Exporter 实现类。然后跟之前一样,我们在工厂类里面,初始化一个 map,通过遍历枚举类,将每个 Exporter 实现类的实例放入 map 中,再在里面实现一个根据 String 类型的文件类型获取 Exporter 实例的静态方法。这样我们就可以在之后调用时,使用工厂类的 getExporter 方法,传入文件类型,获取对应的 Exporter 实例,并调用其 export 方法。