设计模式之工厂模式

工厂模式作为设计模式的一种在开发中被普遍使用, 其实应该可以说是最经常使用的一种的了。 它的设计思想也是面向接口,如果细分下来,可以分成两种工厂模式 · 工厂方法 - Factory Method · 抽象工厂 - Abstract Factory

今天先把Factory Method说完,因为Abstract Factory的实现跟Factory Method有点相似,为了区分我们还是明天再接着说Abstract Factory。

工厂方法 - Factory Method

刚接触工厂模式的同学可能很容易被名字混淆,工厂这个工厂那个的, 我建议是直接记英文,这样不容易混淆两者的概念和实现,毕竟像 "抽象","方法"这两个词,在文章中出现频率非常高,会产生阅读疲劳。 所以下面我们统一用 Factory Method来说明吧。

举例

讲抽象原理不如直接上例子来的直接。 举个简单的例子,现在需要获得不同的颜色,在没有使用 Factory Method之前,我们的代码看起来可能是这样的

Red red = new Red();
Green green = new Green();
Blue blue = new Blue();
....
red.paint();
green.paint();
blue.paint();

这样没有什么问题,但是代码不够灵活。试想一下如果我们不想要红色了,要修改 Red变成 Yellow,除了实例化的代码,下面还有引用的代码,要改的地方就很多了。 而且从使用者的抽象角度来说,新建对象是一个过程,而不是一个操作,使用者需要关心具体的实例化过程,和实例化的使用,这不是面向对象的好思路。 Factory Method 可以解决这种问题,它把使用者和实例的生产逻辑解耦,从而让使用者只关心实例的使用过程。

Factory Method

对于以上代码,可以看出每个颜色都有共同的方法 paint(),这可以作为一个方法抽象出来,

interface Color {
 void paint();
}

具体的颜色类,这里只举一个类,其他都一样,

public class Red  implements  Color {
    public void paint(){
        System.out.println("paint red");
    }
}

Factory

对于 Factory来说,它负责具体的实例生产过程, 可以这么想象,我不关心 Red实例是怎么来的,我只告诉 Factory我要什么颜色,Factory交给我之后,我只需要调用 paint()接口就行。 所以对于调用者来说,现在的代码可能是这样的,

Color color = ColorFactory.create("red");
....
color.paint();

现在看,是不是在调用者的代码里完全没有出现跟实例生产相关的代码了? 即使后面需要修改具体的颜色,也只需要改掉 create("red") 里的参数就可以。

现在来看看 Factory的代码,

class ColorFactory {
    public static Color create(String color) {
        switch(color) {
            case "red":
                return new Red();
            break;
            ....
        }
    }
}

为了简化代码这里只列出了 Red相关的引用。 so…这就是 Factory Method的精髓所在,通过 Factory把实例的生产过程隐藏起来。

但如果你想深一层,这样的简易版Factory Method也会有问题。 如果后面引入的颜色越来越多, ColorFactory的代码量就会变得越来越长,如果实例化的细节足够复杂,那么 ColorFactory也会变成一个超级上帝类。

Factory Method的进化版

为了避免 ColorFactory被迭代到超级上帝类,可以进一步优化代码。 对于 Factory来说,它只关心一件事情,就是生产实例,所以对于这部分的操作,可以抽象出来作为一个接口 create(),

interface Factory {
    Color create();
}

现在开始,我们就可以抛弃 ColorFactory这个超级上帝类了,对于每种Color,可以有一个Factory,

public class FactoryRed implements Factory {
    Color create() {
        return new Red();
    }
}

public class FactoryBlue implements Factory {
    Color create() {
        return new Blue();
    }
}

这样带来的好处是,每当需要引入新的 Color实现时,只需要新增一个类来实现 Factory接口就可以,而不用再往 ColorFactory里塞代码, 使用者的代码会变成这样,

Factory factory = new FactoryRed();
Color color = factory.create();
color.paint();

相对于简单版的 Factory Method,虽然多了一行代码,但是灵活性不变, 即使需要修改 color实例的具体实现,也只需要修改 FactoryRed成你需要的类就行。

总结

Factory Method是开发的利器, 它可以很好的隔离使用者和生产者的逻辑,从而让使用者能灵活的使用,也只需要关心对象能使用的操作,而不需要关心对象的生产过程。 当你的代码规模变到足够大时,就需要考虑将 Factory进一步解耦,用不同的Factory去生产对应的实例。 如果是在一个团队里开发的话,甚至可以通过这种方式把各个具体的Factory分散到不同的小组去让大家各自实现。

原文发布于微信公众号 - Android每日一讲(gh_f053f29083b9)

原文发表时间:2018-05-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏后端技术探索

非Java程序员竟鲜有人真正理解DI和IOC

小编在后端圈也算是阅人无数了, 发现一个现象,Java程序员对于面向对象语言的基础知识整体掌握比较扎实,而类似PHP,Python的初级甚至中级程序员就比较薄弱...

2082
来自专栏KK的小酒馆

Android设计模式二

在组件构建过程中,某些接口之间直接的依赖常常会带来很多问题,甚至根本无法实现。采用添加一层间接(稳定)接口,来隔离本来互相紧密关联的接口是一种常见的解决方案。

1112
来自专栏NetCore

[原创]Fluent NHibernate之旅(三)-- 继承

经过了“开篇”和“简单映射”两篇文章,相信大家对Fluent NHibernate 有了一定的了解了,FluentNHibernate实际就是对 NHibern...

2028
来自专栏数据库

httpclient如何快速往数据库里添加测试用例

本人在使用httpclient做接口测试的过程中,使用数据库管理用例,其中存的key-value的形式,由于接口的参数可能比较多,所以一个个用例写起来会比较麻烦...

2029
来自专栏Android机动车

轻松又酷炫地实现弹幕效果——手把手教学

CSDN: http://blog.csdn.net/jiashuai94

1461
来自专栏Java呓语

生成器模式(分离部件构造)

生成器模式的主要功能是构建复杂的产品,而且是细化的,分步骤的构建产品,也就是生成器模式重在解决一步一步构造复杂对象的问题。如果光是这么认识生成器模式的功能是不够...

932
来自专栏tkokof 的技术,小趣及杂念

Coroutine,你究竟干了什么?(小续)

前篇中讲了一些自己关于Coroutine的理解,后来陆陆续续的又想到了一些,在此简单记录一下,内容不多,故作“小”续吧 :)

872
来自专栏木木玲

设计模式 ——— 适配器模式

1737
来自专栏编程

工厂模式进阶之Android中工厂模式源码分析

Android工厂模式源码分析 本文对Android源码中所涉及到的工厂模式进行分析(源码不会涉及的具体的细节,具体细节读者请另查相关阅资料),最后再给出安卓中...

2339
来自专栏androidBlog

观察者设计模式 Vs 事件委托(java)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gdutxiaoxu/article/details/...

1762

扫码关注云+社区

领取腾讯云代金券