您的位置 首页 java

深入剖析 Android 设计模式中的简单工厂模式

前言

工厂模式 是最常用的一类创建型设计模式; 我们所说的工厂模式是指工厂方法模式,它也是使用频率最高的工厂模式

简单工厂模式是工厂方法模式的小弟; 它不属于GoF 23种设计模式,但是在 软件开发 中应用也颇为频繁,通常将它作为学习其它工厂模式的入门

简单工厂模式的流程

首先简单工厂模式不属于GoF 23种经典设计模式,但通常将它作为学习其它工厂模式的基础,它的设计思想很简单,基本流程如下:

模式定义

简单工厂模式 又称为静态工厂模式,这个模式数据创建式模式; 在简单工厂模式中,根据传入的参数,返回不同类的实例

模式结构

简单工厂模式包含如下角色:

  • 1.Factory:工厂角色

工厂角色负责实现创建所有实例的内部逻辑

  • 2.Product:抽象产品角色

抽象产品角色是所创建的所有对象的父类,负责描述所有实例所共有的公共接口

  • 3.ConcreteProduct:具体产品角色

具体产品角色是创建目标,所有创建的对象都充当这个角色的某个具体类的实例

简单工厂模式主要用来解决 创建实例 的问题

具体代码如下:

 <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="csharp" cid="n14" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px;  padding : 8px 4px 6px; margin-bottom: 15px;  margin -top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px;  text-decoration -style: initial; text-decoration-color: initial;">public  abstract  class CashSuper {
 public abstract int acceptCash(int money);
}</pre>  
 <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n18" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public class CashNormal extends CashSuper {

 @Override
 public int acceptCash(int money) {
 return money;
 }
}</pre>  
 <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="java" cid="n21" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public class CashRebate extends CashSuper {
  private  int moneyRate = 0;

 public CashRebate(int moneyRate) {
 this.moneyRate = moneyRate;
 }

 @Override
 public int acceptCash(int money) {
 return money * this.moneyRate;
 }
}</pre>  
 <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="csharp" cid="n24" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public class CashFactory {
 public  static  CashSuper getCash(int cashOption) {
 CashSuper cashSuper = null;
 switch (cashOption) {
 case 1 :
 cashSuper = new CashNormal();
 break;
 case 2 :
 cashSuper = new CashRebate(2);
 break;
 default:
 break;
 }
 return cashSuper;
 }
}</pre>  
 <pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="csharp" cid="n27" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">public class CashClient {
 public static  void  main(String[] args) throws Interrupted Exception  {
 System.out.println("请选择结算方式:");
 System.out.println("1 --- 原价");
 System.out.println("2 --- 2倍的价格");
 CashSuper cashSuper = null;
 Scanner scanner = new Scanner(System.in);
 switch(scanner.next()) {
 case "1" :
 cashSuper = CashFactory.getCash(1);
 System.out.println(cashSuper.acceptCash(100));
 break;
 case "2" :
 cashSuper = CashFactory.getCash(2);
 System.out.println(cashSuper.acceptCash(100));
 break;
 }
 }
}</pre>  

在简单工厂模式结构图中包含3个角色:

  1. Factory(工厂角色) :即工厂类,它是简单工厂模式的核心,负责实现创建所有产品实例的内部逻辑;工厂类可以被外界直接调用,创建所需的产品对象;在工厂类中提供了静态的工厂方法FactoryMethod(),返回抽象产品类型 Product
  2. Product(抽象产品角色) :它是工厂类创建所有对象的父类,封装了各种产品对象的公共方法;抽象产品的引入将提高系统的灵活性,使得在工厂类中只需定义一个通用的工厂方法,因为所有创建的具体产品对象都是其子类对象
  3. ConceteProduct(具体产品角色) :它是简单工厂模式的创建目标,所有被创建的对象都充当这个角色的某个具体类的实例;每个具体产品角色都继承了抽象产品角色,需要实现抽象产品中声明的抽象方法

具有以下几项原则

1. 单一职责原则

单一职责原则 ,就一个类而言,应该仅有一个引起它变化的原因

  • 核心是 解耦 和增强内聚性
  • 场景 :T负责两个不同的职责:职责P1,职责P2;当由于职责P1需求发生改变而需要修改类T时,有可能会导致原本运行正常的职责P2功能发生故障;也就是说职责P1和P2被耦合在了一起

2. 开放封闭原则

开放封闭原则 ,是说软件实体(类、模块、函数等)可以扩展,但是不可修改

  • 对于扩展是开放的,对于更改是封闭的
  • 提前知道哪些可能发生变化(需要扩展),哪些不会发生变化

3.依赖倒转原则

高层模块不应该依赖底层模块 抽象不应该依赖细节,细节应该依赖抽象

  • 业务场景 :高层模块需要调用底层数据库模块,当需求高层模块用不同的方式调用底层数据库时,就会出现

4. 里氏代换原则

子类型必须能够替换掉它们的父类型

  • 这样由于子类的替换性,就可以在父类无需修改的基础上对父类进行扩展

模式优点

工厂内含有必要的判断逻辑,可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅“消费”产品; 简单工厂模式通过这种做法实现了对责任的分割,它提供了专门的工厂类用于创建对象

客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可; 对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量

通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类,在一定程度上提高了系统的灵活性

模式缺点

由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,整个系统都要受到影响; 使用简单工厂模式将会增加系统中类的个数,在一定程序上增加了系统的复杂度和理解难度

系统扩展困难; 一旦添加新产品就不得不修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护

简单工厂模式由于使用了静态工厂方法,造成工厂角色无法形成基于继承的等级结构

以上就是简单工厂模式的相关内容,此外,作为开发人员为用户带去操作流畅丝滑的APP,是漫长职业生涯当中的终极目标

好了,文章基本上就到这里,简单工厂模式已经分析完毕了!,如有地方不对或者有不同理解的可以提出来

有需要更多Android资讯的同学 可以 私信 发送 “笔记” 或 “进阶” 即可 免费获取

现在私信还可以获得 更多《Android 学习笔记+源码解析+面试视频》

最后我想说:

对于 程序员 来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们

技术是无止境的,你需要对自己提交的每一行代码、使用的每一个工具负责,不断挖掘其底层原理,才能使自己的技术升华到更高的层面

Android 架构师之路还很漫长,与君共勉

文章来源:智云一二三科技

文章标题:深入剖析 Android 设计模式中的简单工厂模式

文章地址:https://www.zhihuclub.com/187860.shtml

关于作者: 智云科技

热门文章

网站地图