工厂设计模式 - 数据存储的特有方式

任何设计模式都是为了解决某些特定场景下所遇到的问题,要知道设计模式其实是可以有一些变动的,说白了设计模式是一种思想而并非一种代码,不要为了使用某种模式生搬硬套。当我们理解一种设计模式的思想时,不要去钻牛角尖。我们在开发中遇到一些问题的时候,就可以在脑海中翻一翻我们所积攒的知识,是不是可以用某一些设计模式来解决这个问题,又或者是用其他方式来解决。当然我们也需要去看一些文章和书籍,很多都写得非常不错,但是我们不能只了解书中所说的例子如: 小轿车的创建过程,电脑的组装,银行办理业务等等,更多需要花时间去思考,怎样用我们自己的项目框架中,否则看过了大量的文章和书籍,发现好像知道那么回事,但就是项目中不知道怎么用。思想要打通,但实战更为重要。

1.问题思考


仍记得去年刚到公司那会,跟着大家伙一起工作,那时公司已有 7 个人在做 android 开发,我也不知道整个项目写得怎样,我看了大部分代码,发现很多有问题,其中保存用户信息是这么写的:

ACache mCache = ACache.get(this);
mCache.put("userName", "darren");
mCache.put("userHeader", "http://www.xxxxx.jpg");

当时看到这个代码我就在想后面肯定会有问题,先不说没有用 LoginSession 去管理,单拿数据的存储来说,这样直接写肯定是有问题的。因为今天的主要内容讲的是讲工厂设计模式,这里我就不说与 LoginSession 相关的内容,也不说这个框架 ASimpleCache 怎么样,今天特意查了一下有 2000+ 的star。果不其然后面快要上线的时候,因为当时由于清理缓存的功能,需要清理某一部分数据,但是部分数据(用户信息)是需要保留的,当我们调用 clear 的方法是全部清理。这个时候摆在我们面前的解决方法有很多,第一种,干脆就不做清理只是做一个假数据的显示和 Toast ;第二种,把用户信息用另一种缓存存着;第三种,就是把 ASimpleCache 的依赖删除,统统改掉。第一种可能是最快的方式,第三种是最慢的,后来经过商量之后还是决定全部改掉,并且由我来改采用第三种方式。好在当时只有 20+ 的地方用了,大概改了一个小时就改好了,把依赖去掉,哪里报错改哪里。当我们碰到这个问题的时候,我想应该不是立马去解决问题,就像我文章开头所说的一样,而是想避免下次再出现这样的问题,今天我们就用工厂设计模式,看下数据存储应该怎么存。

2.工厂设计模式介绍


2.1 模式定义

定义一个创建对象的接口,让子类决定实例化哪个类,而对象的创建统一交由工厂去生成,既做到了解耦也保证了最少知识原则。一般分为三类:简单工厂模式,工厂方法模式,抽象工厂模式

2.2 简单工厂模式

目前按照数据的存储我们一般是有这么几类,内存,SharedPreferences,数据库,磁盘,存储的数据一般分为基本数据类型和对象,先上 UML 图

简单工厂UML.png
public class IOFactory implements Factory{
    // 通过 Factory 去创建 IOHandler 对象
    public static IOHandler createIOHandler(IOType type){
        switch (type){
            case IOType.MEMORY:
                // 内存缓存
                return new MemoryIOHandler();
            case IOType.PREFERENCES:
                // Preferences缓存
                return new PreferencesIOHandler();
            case IOType.DISK:
                // 磁盘缓存
                return new DiskIOHandler();
            default:
                return null;
        }
    }
}
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 获取磁盘缓存的 IOHandler 
        IOHandler ioHandler = IOFactory.createIOHandler(IOFactory.IOType.DISK);
        // 保存数据
        ioHandler.save("userName","darren");
        ioHandler.save("userPwd","940223");
    }

    public void click(View view){
        // 获取磁盘缓存的 IOHandler 
        IOHandler ioHandler = IOFactory.createIOHandler(IOFactory.IOType.DISK);
        // 获取数据
        String userName = ioHandler.getString("userName");
        String userPwd = ioHandler.getString("userPwd");
        Log.e("TAG","userName = "+userName+" userPwd = "+userPwd);
    }
}

上面就是我们的简单工厂模式,就这么简单,可以看到我们不是直接通过 new 对象来保存数据的,而是用不同的类型,通过 IOFactory 去创建我们的对象。这样目前来讲也看不出什么好处,而且问题还是有很多。

2.3 工厂方法模式

IOFactory 掌管了所有的业务逻辑处理。这样的类,我们称为上帝类/全能类。上帝类耦合度非常高,每当需要增加一种缓存是,就需要大量更改 IOFactory 中的代码,而且也不符合开闭原则,比如我想加一个 DatabaseIOHandler 等等。接下来看下工厂方法模式, 先上 UML 图

工厂方法模式UML.png
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 创建 IOFactory 生成 IOHandler
        DiskIOFactory diskIOFactory = new DiskIOFactory();
        IOHandler ioHandler = diskIOFactory.createIOHandler();
        // 保存数据
        ioHandler.save("userName","darren");
        ioHandler.save("userPwd","940223");
    }

    public void click(View view){
        // 创建 IOFactory 生成 IOHandler
        DiskIOFactory diskIOFactory = new DiskIOFactory();
        IOHandler ioHandler = diskIOFactory.createIOHandler();
        // 获取数据
        String userName = ioHandler.getString("userName");
        String userPwd = ioHandler.getString("userPwd");
        Log.e("TAG","userName = "+userName+" userPwd = "+userPwd);
    }
}

工厂方法模式也是很好理解的,这个时候我们想增加 DatabaseIOHandler 就只需要新增 DatabaseIOFactory 创建一个 DatabaseIOHandler 就行了,而不是去修改我们原来的代码。但是随着数据存储方式的增加,相应的工厂类也会同比增加,造成项目文件十分臃肿巨大。我们可能也需要好好考虑,到底要不要用,于是为了减少工厂类的出现数量,抽象工厂模式诞生了。

2.4抽象工厂模式

抽象工厂模式UML.png
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 获取默认的 IOHandler , 默认是磁盘存储
        IOHandler ioHandler = IOFactory.getFactory().getDefaultIOHandler();
        // 保存数据
        ioHandler.save("userName","darren");
        ioHandler.save("userPwd","940223");
    }

    public void click(View view){
        // 获取默认的 IOHandler , 默认是磁盘存储
        IOHandler ioHandler = IOFactory.getFactory().getDefaultIOHandler();
        // 获取数据
        String userName = ioHandler.getString("userName");
        String userPwd = ioHandler.getString("userPwd");
        Log.e("TAG","userName = "+userName+" userPwd = "+userPwd);
    }
}

最近有很多认识的哥们在找工作,都说感觉不是很好找,很多哥们都给我看了简历,换工作之前要想好准备好,骑驴找马等等这里先不说,单拿我看的简历来讲,简历一定要有突出的亮点,比如你会用 RXjava+OKhttp+Retrofit 来做项目,我想很多人都会用,如果你能知道原理这就算是一个亮点,而面试的时候我一般也会问一些这方面的内容,又或者你看过大量的 FrameWorker 层的源码,读过大公司的一些开源框架像阿里腾讯的热修复源码,360和滴滴的插件化开发源码等等,当然最好是去读最新版的,这些都算是亮点。

所有分享大纲:Android进阶之旅 - 系统架构篇

视频讲解地址:http://pan.baidu.com/s/1hrSaQl2

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容