​ 工厂模式是一种非常常用的创建型设计模式,其提供了创建对象的最佳方式。在创建对象时,不会对客户端暴露对象的创建逻辑,而是通过使用共同的接口来创建对象。通过使用工厂模式,在业务代码中可以灵活的操控生成的实例对象。

​ 工厂模式主要包含以下三种实现:简单工厂、工厂方法及抽象工厂。下面我们来逐一了解这三种工厂方法的实现与异同。

简单工厂

​ 工厂模式中,最简单易懂的就是简单工厂方法。通俗点来说,简单工厂的核心思想就是:“你告诉我你需要什么,我就为你生产什么”。这里举一个游戏的简单例子。一个游戏中角色分别有战士、法师、精灵。而我们需要设计一个相应的铁匠铺。根据不同的角色,来锻造不同的武器。(假设战士是剑、法师是法杖,而精灵是弓)

​ 那么编程思路其实很简单,首先我们需要设计一个Player的基类对象,并定义一个基本的玩家类型Type字段,用于判断当前玩家是什么角色。然后分别定义出战士、法师和精灵的对象。并对getType的方法进行覆盖。简单类图如下:

​ 具体类方法如下:

//玩家类
public class Player {String name;int type;public Player(String name) {this.name = name;}
}
public class Warrior extends Player {@Overridepublic int getType() {return PlayerEnum.WARRIOR.getCode();}
}

​ 在定义完玩家类以后,我们就可以设计咱们的铁匠铺类了。简单来说,铁匠铺只需要调用getType方法判断当前玩家的角色,并锻造武器即可。

@Slf4j
public class BlackSmithShopSimpleFactory {public static Weapon createWeapon(Player player) {//简单工厂中设计判断即可Weapon weapon = null;if (player.getType() == WARRIOR.getCode()) {weapon = new Sword();} else if (player.getType() == ELF.getCode()) {weapon = new Bow();} else if (player.getType() == MAGE.getCode()) {weapon = new Staff();}return weapon;}public static void main(String[] args) {Player player1 = new Warrior();Weapon weapon1 = createWeapon(player1);System.out.println("player1从铁匠铺获取到的武器是:"+weapon1.getDesc());Player player2 = new Mage();Weapon weapon2 = createWeapon(player2);System.out.println("player2从铁匠铺获取到的武器是:"+ weapon2.getDesc());Player player3 = new Elf();Weapon weapon3 = createWeapon(player3);System.out.println("player3从铁匠铺获取到的武器是:"+ weapon3.getDesc());}
}

​ 最终的输出结果如下:

​ 可以看到,简单工厂在对应不同玩家的时候都能生成出相应的对象,实现了灵活的机制。但是需要注意的是,简单工厂其实是违背了开闭原则的。例如我们可能需要新增玩家角色 - 刺客,其使用的武器是飞镖,那么此时我们就需要修改铁匠铺的代码,新增上飞镖这种类型。

​ 简单工厂代码虽然违反了开闭原则且可能需要频繁增加生成代码,但是胜在简单易实现,且可读性较好。大多数时候都能胜任问题。

工厂方法

​ 工厂方法模式是对简单工厂模式的进一步深化,其不像简单工厂模式通过一个工厂来完成所有对象的创建,而是通过不同的工厂来创建不同的对象,每个对象有对应的工厂创建。

​ 依旧是以上面的游戏为例子,假设游戏当前不再针对职业进行武器的限制了。玩家可以任意地选择合适的武器,那么此时就可以采用工厂方法进行改造。

​ 首先,定义一个抽象类或接口,其中规定咱们的创建武器的方法。然后,分别定义生产法杖、生产弓和生产剑的铁匠铺。并实现对应的方法。紧接着,根据玩家的具体需要去生成相应的武器即可。选择工厂并生产的代码如下:

public class BlackSmithShopFactoryPattern {public static void main(String[] args) {Player player = new Player();//生产剑的铁匠铺WeaponShop swordShop = new SwordShop();Weapon weapon = swordShop.createWeapon();System.out.println("玩家选择的武器为:"+weapon.getDesc());//生产弓的铁匠铺WeaponShop staffShop = new StaffShop();Weapon weapon1 = staffShop.createWeapon();System.out.println("玩家选择的武器为:"+weapon1.getDesc());//生产法杖的铁匠铺BowShop bowShop = new BowShop();Weapon weapon2 = bowShop.createWeapon();System.out.println("玩家选择的武器为:"+weapon2.getDesc());}
}

​ 最终的结果如下:

​ 工厂方法的优势在于扩展性相对比较好,当需要新增工厂的时候,只需要进行相应的拓展即可实现。例如我们如果要新增武器,只需要写一个类再实现相应的生产武器的方法即可。

​ 但是,问题在于过多的类很可能会影响整个系统的可读性,增大系统的复杂度。

抽象工厂

​ 抽象工厂,其实是工厂方法的拓展。上述无论是工厂方法还是简单工厂,都是针对一个对象进行设计和封装,但是实际情况中往往会存在一些连带的情况。还是以上述游戏的情况为例子。假设当前我们要打造的不再是单一的武器,而是需要打造对应的武器和盔甲。同时,武器和盔甲必须成套打造才有相应的属性加成。那么这个时候,工厂方法和简单工厂就比较难满足我们的需求了。

​ 针对这个情况,我们可以设计相应的抽象工厂解决。这里我们首先假定套装有两套,黑龙套装和红龙套装。

​ 首先咱们先设计一个抽象的套装工厂,其两个方法分别是生产武器和盔甲。

public abstract class SuitShop {public abstract Weapon createWeapon();public abstract Armor createArmor();
}

​ 随后根据职业和套装指定相应的工厂实现子类。(这里仅仅实现了战士的工厂实现子类,其余角色的子类实现类似)

public class RedDragonWarriorSuitShop extends SuitShop{@Overridepublic Weapon createWeapon() {return new RedDragonSword();}@Overridepublic Armor createArmor() {return new RedDragonPlate();}
}
public class BlackDragonWarriorSuitShop extends SuitShop{@Overridepublic Weapon createWeapon() {return new BlackDragonSword();}@Overridepublic Armor createArmor() {return new BlackDragonPlate();}
}

​ 除了工厂,我们还要定义对应的黑龙套装和红龙套装对应的武器和盔甲的子类。

public class BlackDragonSword extends Sword{@Overridepublic String getDesc() {return "黑龙剑";}
}
public class BlackDragonPlate extends Plate{@Overridepublic String getDesc() {return "黑龙板甲";}
}
public class RedDragonPlate extends Plate{@Overridepublic String getDesc() {return "红龙板甲";}
}
public class RedDragonSword extends Sword{@Overridepublic String getDesc() {return "红龙剑";}
}

​ 最终定义的整体类图如下所示:

public class BlackSmithShopAbstractFactory {public static void main(String[] args) {SuitShop suitShop = new BlackDragonWarriorSuitShop();Weapon weapon = suitShop.createWeapon();Armor armor = suitShop.createArmor();System.out.println("玩家打造的套装是:"+weapon.getDesc()+"和"+armor.getDesc());SuitShop redDragonWarriorSuitShop = new RedDragonWarriorSuitShop();Weapon weapon1 = redDragonWarriorSuitShop.createWeapon();Armor armor1 = redDragonWarriorSuitShop.createArmor();System.out.println("玩家打造的套装是:"+weapon1.getDesc()+"和"+armor1.getDesc());}
}

​ 在main方法中定义相应的逻辑,然后执行得到如下结果。

​ 总的来说,抽象工厂主要是针对多个类型对象的时候使用的方法。但其缺点也很明显,首先是需要增加较多的类来实现相应的逻辑。其次是该方式也不符合开闭原则,如果需要修改的时候,是需要对工厂和对象都进行相应的代码修改的。例如如果需要再增加一个头盔,就可能影响到各个套装都需要增加对头盔的锻造逻辑的实现。

总结

​ 本文介绍了工厂模式对应的三种不同实现方法,包括简单工厂工厂方法以及抽象工厂。三种实现方法也各有优劣。

  1. 简单工厂,逻辑简单,代码逻辑易懂,但是不符合开闭原则,增加工厂需要改动相应的判断逻辑。
  2. 工厂方法,对于简单工厂做了进一步的抽象,新增工厂只需要新增加相应的工厂类即可,不涉及到工厂判断的逻辑。但是会存在多个工厂的情况下,类的数目增多的情况。
  3. 抽象工厂,是对于工厂方法的进一步抽象,其支持同时生生成多个对象。通过新增加工厂类可以新增加需要生成的组合对象。但是问题在于其也违背了开闭原则,当需要生成的对象数量增多时,相应的逻辑需要进行修改和增加。

工厂模式:优雅地生成多种类型对象相关推荐

  1. java为什么用工厂模式_为什么用简单工厂模式,而不是直接实例化对象

    一开始了解了"简单工厂模式"之后,在关于为什么不直接实例对象,而是利用工厂类来实例对象产生了疑惑. 经过多种渠道的了解,我最后的观点是:这个工厂类不仅仅就只能有实例化对象这一个功能 ...

  2. 四个Webix实例:生成多种类型的JavaScript列表

    在这篇文章中,我们将介绍如何创建使用各种类型列表显示数据的Web组件.具体而言,我们采用的是Webix UI库.要理解Webix UI的工作机制,我们将会创建一个简单的小组件,以列表形式显示JSON数 ...

  3. 【Python】random模块生成多种类型随机数

    开发和测试过程中我们经常遇到需要随机数的场景,比如为了用户密码更安全我们有时会加入随机码,也就是将用户原密码连接上一串随机字符然后加密保存,又比如我们可能需要随机展示某张图片等等.这篇文章主要介绍了各 ...

  4. 深入理解工厂模式——由对象工厂生成对象

    目录: 一 工厂模式介绍 1.1 工厂模式的定义 1.2 工厂模式的分类: 1.3 在开源框架中的使用 1.4 为什么要用工厂模式 二 简单工厂模式 2.1 介绍 2.2 适用场景 2.3 简单工厂模 ...

  5. java设计模式中不属于创建型模式_23种设计模式第二篇:java工厂模式定义:工厂模式是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式...

    23种设计模式第二篇:java工厂模式 定义: 工厂模式是 Java 中最常用的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 工厂模式主要是为创建对象提供过渡接口, ...

  6. 调用工厂模式来实现对象实例化

    1 工厂模式的作用,为什么要用工厂模式? 工厂模式是为了解耦:把对象的创建和使用的过程分开.就是Class A 想调用Class B,那么只是调用B的方法,而至于B的实例化,就交给工厂类. 工厂模式可 ...

  7. 游戏编程模式-类型对象

    "通过创建一个类来支持新类型的灵活创建,其每个实例都代表一个不同的对象类型." 动机 在RPG游戏中,我们通常会创建很多的怪物来作为我们主角的敌人,比如说恶龙.野狼等.怪物具有一系 ...

  8. 抽象工厂模式 java实例 tclhaier_Unity常用的设计模式_工厂模式系列之抽象工厂模式...

    在工厂方法模式中,工厂只负责生产具体的产品,每一个具体的工厂对应着一个具体的产品,工厂方法也具有唯一性,如果有时候我们需要一个工厂方法提供多个产品而不是一个单一的产品,例如:海尔品牌不止生产海尔TV, ...

  9. 三种工厂模式的分析以及C++实现

    三种工厂模式的分析以及C++实现 简单工厂模式 简单工厂模式是工厂模式中最简单的一种,他可以用比较简单的方式隐藏创建对象的细节,一般只需要告诉工厂类所需要的类型,工厂类就会返回需要的产品类,但客户端看 ...

最新文章

  1. 块存储、文件存储、对象存储这三者和分布式文件存储系统的本质区别
  2. Tableau必知必会之学做 饼图 和 折线图 的组合图表
  3. PHP面向对象设计模式
  4. 阿里云发布“码上公益”平台 打造更高效透明的“科技公益”
  5. Underfull hbox (badness 10000) in paragraph at lines 83--86
  6. vue更新路由router-view复用组件内容不刷新
  7. 【Alpha】Scrum Meeting 1
  8. MyBatis学习--查询缓存
  9. Rhino(Grasshopper)+PaddleX快速建模
  10. 利用Trie(字典树)实现敏感词过滤算法
  11. filmimpact安装教程,PR插件『FilmImpact.net』下载与安装教程
  12. matlab等距偏置曲线,144 偏置曲线命令详解
  13. 简单阐述标准盒模型和怪异盒模型的差别和区别
  14. Fairy tale(BFS + 大模拟)
  15. 2u机架式服务器作用,不仅是一款通用的2U机架式服务器还具有足够的扩展力
  16. java对象实例化内存布局与访问定位
  17. 年已过,新的一年如何过?
  18. C#技术分享【Word转换成图片和PDF——2种方案】
  19. Data Science 到底是什么?
  20. 联合概率,边际概率和条件概率

热门文章

  1. unbind()解决多次弹窗问题
  2. 《Unity游戏优化》笔记(11)[21/03/08_周一][126_132]
  3. selenium IE保护模式报错解决方案(使用python写注册表)
  4. matlab中rmse是什么意思,matlab sse和rmse
  5. 远程桌面连服务器踩过的所有坑(一、win10升级专业版)
  6. 重温操作系统——“共享”CPU
  7. React测试框架之enzyme
  8. HTML5学习笔记 —— JavaScript基础知识
  9. 男人可以为女人做的50件事
  10. TEXlive+textmaker