小明开发的应用,经常要从XML或者Asset中读取省市区数据。

小明是这样写的:

public abstract class IOHandler {/*** 添加*/public abstract void add(String id, String name);/*** 删除*/public abstract void remove(String id);/*** 修改*/public abstract void update(String id, String name);/*** 查询*/public abstract String query(String id);
}
public class XMLHandler extends IOHandler {@Overridepublic void add(String id, String name) {//业务处理}@Overridepublic void remove(String id) {//业务处理}@Overridepublic void update(String id, String name) {//业务处理}@Overridepublic String query(String key) {return "xml";}
}
public class AssetHandler extends IOHandler {@Overridepublic void add(String id, String name) {//业务处理}@Overridepublic void remove(String id) {//业务处理}@Overridepublic void update(String id, String name) {//业务处理}@Overridepublic String query(String name) {return "asset";}
}
    public void test() {IOHandler asset = new AssetHandler();String result = asset.query("city.txt");System.out.println("result:" + result);IOHandler xml = new XMLHandler();result = xml.query("city");System.out.println("result:" + result);}

输出结果

result:asset
result:xml

小明的领导一看,说这样写不行,如果AssetHandler换一种实现方式,岂不是每个引用的地方都要改变?假如以后不想通过这些方式读取城市数据,要增加一个读取本地文件的方式,改动起来很不方便。

领导说生成这种具有相同功能的对象,可以使用工厂模式。

使用工厂模式改造

小明觉定用简单工厂尝试改造,增加一个工厂来负责生成对象

public class SimpleFactory {public IOHandler getHandler(String type) {IOHandler ioHandler = null;switch (type) {case "xml":ioHandler = new XMLHandler();break;case "asset":ioHandler = new AssetHandler();break;default:break;}return ioHandler;}}
    public void test() {SimpleFactory factory = new SimpleFactory();IOHandler asset = factory.getHandler("asset");String result = asset.query("city.txt");System.out.println("result:" + result);IOHandler xml = factory.getHandler("xml");result = xml.query("city");System.out.println("result:" + result);}

小明的领导一看,如果要增加新的对象,或者增加一些业务逻辑,岂不是要修改工厂,工厂因此变得复杂和臃肿。

小明决定使用工厂方法改造:

public class AssetFactory implements IFactory {@Overridepublic IOHandler getHandler() {return new AssetHandler();}
}
public class XMLFactory implements IFactory {@Overridepublic IOHandler getHandler() {return new XMLHandler();}
}
    public void test() {IFactory assetFactory = new AssetFactory();IFactory xmlFactory = new XMLFactory();IOHandler asset = assetFactory.getHandler();String result = asset.query("city.txt");System.out.println("result:" + result);IOHandler xml = xmlFactory.getHandler();result = xml.query("city");System.out.println("result:" + result);}

和简单工厂不同的是,工厂方法是多工厂,每个工厂负责生成一个对象。如果要增加新的对象,只需要增加一个工厂即可,具有良好的扩展性。

工厂方法模式是简单工厂演化而来的高级版,后者才是真正的设计模式。

假如情景更复杂呢?
比如说之前的工厂都是小明写的,但不好用,新来的程序员小张想用自己写的呢?
我有那么多工厂,我想要一个超级工厂,去管理这些工厂呢?

这时候就可以用抽象工厂了:

小明写的Handler:

public class XiaomingAssetHandler extends IOHandler {@Overridepublic void add(String id, String name) {//业务处理}@Overridepublic void remove(String id) {//业务处理}@Overridepublic void update(String id, String name) {//业务处理}@Overridepublic String query(String name) {return "xiaoming asset";}
}
public class XiaomingXMLHandler extends IOHandler {@Overridepublic void add(String id, String name) {//业务处理}@Overridepublic void remove(String id) {//业务处理}@Overridepublic void update(String id, String name) {//业务处理}@Overridepublic String query(String key) {return "xiaoming xml";}
}

小张写的Handler

public class XiaozhangAssetHandler extends IOHandler {@Overridepublic void add(String id, String name) {//业务处理}@Overridepublic void remove(String id) {//业务处理}@Overridepublic void update(String id, String name) {//业务处理}@Overridepublic String query(String name) {return "xiaozhang asset";}
}
public class XiaozhangXMLHandler extends IOHandler {@Overridepublic void add(String id, String name) {//业务处理}@Overridepublic void remove(String id) {//业务处理}@Overridepublic void update(String id, String name) {//业务处理}@Overridepublic String query(String key) {return "xiaozhang xml";}
}

创建抽象工厂

public interface AbstractFactory {IOHandler getXMLHandler();IOHandler getAssetHandler();}

创建小明的具体工厂

class XianmingFactory implements AbstractFactory{@Overridepublic IOHandler getXMLHandler() {return new XiaomingXMLHandler();}@Overridepublic IOHandler getAssetHandler() {return new XiaomingAssetHandler();}}

创建小张的具体工厂

class XianzhangFactory implements AbstractFactory{@Overridepublic IOHandler getXMLHandler() {return new XiaozhangXMLHandler();}@Overridepublic IOHandler getAssetHandler() {return new XiaozhangAssetHandler();}}

创建超级工厂


public class FactoryProducer {public AbstractFactory getFactory(String type) {AbstractFactory factory = null;switch (type) {case "xiaoming":factory = new XianmingFactory();break;case "xiaozhang":factory = new XianzhangFactory();break;default:break;}return factory;}}

开始测试

 public void test() {FactoryProducer factoryProducer = new FactoryProducer();//创建小明工厂AbstractFactory xiaomingFactory = factoryProducer.getFactory("xiaoming");//创建小张工厂AbstractFactory xiaozhangFactory = factoryProducer.getFactory("xiaozhang");//使用小明写的Asset读取方式IOHandler ioHandler = xiaomingFactory.getAssetHandler();String result = ioHandler.query("city.txt");System.out.println("result:" + result);//使用小张写的Asset读取方式ioHandler = xiaozhangFactory.getAssetHandler();result = ioHandler.query("city.txt");System.out.println("result:" + result);}

输出结果

result:xiaoming asset
result:xiaozhang asset

可以看到,抽象工厂最核心的是,多工厂,多产品的思路。

比如说富士康在深圳和东莞都有厂,都生产手机和电脑。区别是,深圳生产华为手机和华为电脑,东莞生产苹果手机和苹果电脑。

又比如说游戏里面,角色类型有人族和兽族,角色等级又有低中高级,人族和兽族就是工厂,各自生产低中高级的角色。

工厂方法讲解

看一下工厂方法模式的UML图
每个工厂,去生成各自的产品

抽象工厂方法讲解

看一下工厂方法模式的UML图

有多个工厂,每个工厂生产多个产品

简单工厂、工厂方法、抽象工厂的对比

简单工厂:一个工厂方法生产多个产品
工厂方法:多个具体工厂,一个工厂生产一个产品
抽象工厂:多个具体工厂,一个工厂生产多个产品

拿刚刚游戏里面打比方,简单工厂不符合设计模式规范,而使用工厂方法就要写6个工厂之多,这时候使用抽象工厂就非常适合了。

什么时候用工厂设计模式?

工厂设计模式的核心是:生产产品

什么才叫产品?
比如说自定义的Button,有圆角的,直角的,圆形的
比如说通知栏样式的适配,根据不同的Android系统版本配置不同的样式
比如应用的主题,有深色的、浅色的,主题要配置button、textview、dialog等控件
比如应用的语言,有中文的、英文的

这些都是产品,它们的本质是一样的,但形态又不同。

如果仔细观察,应用内很多地方其实是可以用上工厂设计模式的

【设计模式实战】简单工厂、工厂方法、抽象工厂:原理篇相关推荐

  1. 详解设计模式之工厂模式(简单工厂+工厂方法+抽象工厂)

    园子里关于23种设计模式的博文已经可以说是成千上万.车载斗量.屯街塞巷.不计其数.数不胜数.摩肩接踵.汗牛充栋.车水马龙.门庭若市.琳琅满目直至让人眼花缭乱了.在这样的大环境下之所以来写设计模式类的博 ...

  2. 详解设计模式之工厂模式(简单工厂+工厂方法+抽象工厂) v阅读目录

    1楼留头头大神:http://www.cnblogs.com/toutou/p/4899388.html v阅读目录 v写在前面 v简单工厂模式 v工厂方法模式 v抽象工厂模式 v博客总结 v博客前言 ...

  3. 设计模式学习笔记——03 简单工厂 工厂方法 抽象工厂

    简单工厂 简单工厂模式也成静态工厂模式,但此模式不符合开闭原则,但仍然很常用 适用范围:工厂类需要创建的对象种类比较少,客户端只需要知道传入工厂类的参数,对于如何创建对象(逻辑)不关心 上段代码: p ...

  4. 简单工厂 工厂方法 抽象工厂 如何理解

    文章目录 前言 一.简单工厂 二.工厂方法 三.抽象工厂 总结 前言 简单工厂,工厂方法,抽象工厂,三者有什么区别? 搞清楚他们有什么弊端,以发展的角度去观察,理解会更加深入. 提示:以下是本篇文章正 ...

  5. 设计模式之——简单(静态)工厂模式和抽象工厂模式

    文章目录 [关于设计模式] 设计模式的诞生 设计模式概念与解读 设计模式的原则 [关于工厂模式] 简单工厂(静态工厂)模式的概念 抽象工厂模式 工厂模式的使用时机和注意事项 给自己的思考 [关于设计模 ...

  6. java 三种工厂模式(简单工厂+工厂方法+抽象工厂)

    一.简单工厂模式 概述   简单工厂模式:定义一个工厂类,它可以根据参数的不同返回不同类的 实例,被创建的实例通常都具有共同的父类.因为在简单工厂模式中用于创建实例的方法是静态(static)方法,因 ...

  7. 简单工厂-工厂方法-抽象工厂

    目录 简单工厂 工厂方法 抽象工厂 前言 之前看书认真了解过这三种模式,但因为没有做记录,都给忘完了.现在重新分析网上的博客发现跟书里讲的不太一样,哎-.现在能做的就是把现在的理解给记录一下,若以后有 ...

  8. 【软件设计模式】工厂模式(简单工厂模式、一般工厂模式、抽象工厂模式)

    概述: 工厂模式把对象的创建交由某个特定的类来实现,该类为工厂类,该类的方法称为工厂方法,仅仅负责创建对象,从而将客户端复杂的对象创建语句实现解耦.责任分离,方便扩展和维护. 分类: 工厂模式分为简单 ...

  9. 设计模式理解:工厂模式,抽象工厂,原型方法

    工厂模式.抽象工厂.原型方法都是对象创建型模式.工厂模式的目的是利用抽象类去动态地创建对象:抽象工厂模式是利用抽象类动态地创建一系列的对象:而原型方法是通过克隆(深拷贝)地形式创建出对象 ,再去操作新 ...

  10. Java设计模式(工厂模式>抽象工厂模式和原型模式)

    Java设计模式Ⅱ 1.工厂模式 1.1 简单工厂模式 1.2 工厂方法模式 2.抽象工厂模式 3.总结 4.原型模式 4.1 原型模式 4.2 浅拷贝 4.3 深拷贝 5.建造者模式 1.工厂模式 ...

最新文章

  1. VISP视觉库框架结构与使用入门
  2. c++用一级运算比较大小_阿里百度腾讯 C/C++ 面试题总结,我全都告诉你!
  3. python工程师-Python工程师必看的面试问题与解答(中)
  4. 分区格式化/挂载数据盘
  5. iOS逆向之Protocol Witness Table的汇编实现原理
  6. SQL Server使用视图做权限控制
  7. lstm需要优化的参数_使用PyTorch手写代码从头构建LSTM,更深入的理解其工作原理...
  8. Linux网络编程——tcp并发服务器(I/O复用之select)
  9. 外媒:苹果明年上半年推出iPhone SE 3 支持5G搭载A14处理器
  10. oracle 用户解锁和修改用户密码
  11. @程序员,CSDN“年度征文”开启,快来年终盘点挣大奖吧~
  12. ASA防火墙IPSEC ***配置
  13. 交通路标识别(毕业设计)
  14. 软件技术实训室建设方案(完整版)2022
  15. Migration——迁移
  16. 【操作系统习题】假定某多道程序设计系统供用户使用的主存空间为100 KB ,磁带机2台,打印机1台
  17. 微信小程序-增加水印(自定义内容)
  18. 浮点型数据判断相等不能直接使用==
  19. 零基础HTML教程(4)--动手创建第一个网页吧
  20. Python应用之植物大战僵尸2-功夫世界BOSS关卡无限刷金币

热门文章

  1. Android学习-五布局之绝对布局(AbsoluteLayout)
  2. Oracle OIM 原理
  3. EXE工程和OCX工程的转化(2002/5/30 三金 版权所有)
  4. Linux ❉ top命令详解
  5. caoz的梦呓:谈谈信息不对称与To B业务的难点【推荐】
  6. WEB漏洞-逻辑越权之登录脆弱及支付修改
  7. TXT文档如何更改默认编码格式
  8. husky实现git commit规范
  9. 有哪些好用的日程计划管理软件?
  10. python实现mnist手写数字识别