引言

今天回看之前总结的抽象工厂模式的实现《Java常用设计模式————抽象工厂模式》,聚焦于抽象工厂模式的缺点,试着改进了一下。

回顾一下抽象工厂模式的缺点:

在添加新的产品类型时,难以扩展抽象工厂来生产新种类的产品。

这是怎么回事呢?原来,老套的实现方式是为每种类型的产品都创建一个具体的工厂类,这个类只生产一种特定类型的产品。因此,当有新的类型的产品加入系统时,就必须添加一个对应的工厂类来支持这类产品,不仅不利于扩展,而且会增加大量的工厂类。

例如之前会有如下两个具体产品的工厂类来生产对应类型的产品:

今天试着使用泛型的方式,得出了一种更加通用的抽象工厂实现方式。可以避免大量工厂的再造。

实现

为了本篇文章的完整性,依然将全部实现过程贴出,各位同学可以与《Java常用设计模式————抽象工厂模式》进行比较阅读。

一、抽象化产品族

产品族的概念其实很好理解,每种类型的产品就是一个产品族,它包含多种不同的表现形式,例如汽车就是一个产品族,它包含卡车、轿车等,这些具体的产品隶属于汽车这个产品族。

如图所示,创建了电视产品族和汽车产品族。电视产品族包括索尼电视夏普电视:

public interface Television {void play();
}
public class SonyTV implements Television{@Overridepublic void play() {System.out.println("SonyTV playing...");}
}
public class SharpTV implements Television{@Overridepublic void play() {System.out.println("SharpTV playing...");}
}

汽车产品族包括奥迪汽车奔驰汽车

public interface Car {void run();
}
public class Audi implements Car{@Overridepublic void run() {System.out.println("Audi running...");}
}
public class Benz implements Car{@Overridepublic void run() {System.out.println("Benz running...");}
}

二、创建抽象工厂及泛型工厂

抽象工厂是具体工厂的进一步抽象化,在原版的抽象工厂模式实现中,会存在多个具体的产品工厂,而在本例中,将会以泛型化的实现类来代替它们,而且即便再增加新的产品族也不需要修改泛型工厂:

public interface Factory<T> {T getProduct(Class<? extends T> clazz);
}
public class GenericFactory<T> implements Factory<T> {@Overridepublic T getProduct(Class<? extends T> clazz) {if (clazz == null)return null;try {T obj = (T) clazz.newInstance();return obj;} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();}return null;}
}

三、测试产品的生产

public class MyProgram {public static void main(String[] args) {Factory<Car> carFactory = new GenericFactory<>();Factory<Television> tvFactory = new GenericFactory<>();Car benz = carFactory.getProduct(Benz.class);Car audi = carFactory.getProduct(Audi.class);benz.run();audi.run();Television sonyTV = tvFactory.getProduct(SonyTV.class);Television sharpTV = tvFactory.getProduct(SharpTV.class);sonyTV.play();sharpTV.play();}
}

执行结果:

总结

抽象工厂是一种非常有趣的设计模式,它隔离了对象创建的过程,并且可以应用反射机制来完成这一经典的设计模式。但传统的实现需要具体每一个产品族的工厂,这样就依然没有提高通用性。本例中使用泛型的工厂方式,不需要为具体工厂的创建而增加新的编码。这种方式需要注意泛型的实现,使用<? extends T>可以完美的应对具体产品生产的需要。是一个非常不错的实现手段。

鸣谢

《Java常用设计模式————抽象工厂模式》

《Java泛型初探————泛型通配》

抽象工厂模式升级版————泛型化实现相关推荐

  1. 设计模式之工厂类模式总结对比、简单工厂模式、工厂方法模式、抽象工厂模式、带反射的工厂模式、例子代码分析、最详细

    1. 题目 假设某公司同时用SqlServer.MySql数据库,即会切换两数据库(不同数据库的sql语句有些许差异),同时,两数据库里均有对Users.Departments表的操作(sql代码不一 ...

  2. C++设计模式之抽象工厂模式

    问题描述 之前讲到了C++设计模式--工厂方法模式,我们可能会想到,后期产品会越来越多了,建立的工厂也会越来越多,工厂进行了增长,工厂变的凌乱而难于管理:由于工厂方法模式创建的对象都是继承于Produ ...

  3. 系统架构技能之设计模式-抽象工厂模式

    一.上篇回顾 上篇我们主要讲述了简单工厂模式和工厂模式.并且分析了每种模式的应用场景和一些优缺点,我们现在来回顾一下: 简单工厂模式:一个工厂负责所有类型对象的创建,不支持无缝的新增新的类型对象的创建 ...

  4. Java设计模式之工厂方法模式与抽象工厂模式

    2019独角兽企业重金招聘Python工程师标准>>> 一.前期回顾 上一篇<Java设计模式之单例模式>详细介绍了单例模式,介绍了单例模式的使用场景,优缺点,同时也写了 ...

  5. 设计模式(6)——抽象工厂模式(Abstract Factory Pattern,创建型)

    1.概述 使用设计模式可以提高代码的可复用性.可扩充性和可维护性.抽象工厂模式(Abstract Factory Pattern)属于创建型模式,为创建一组相关或者相互依赖的对象(产品族)提供一个抽象 ...

  6. 小米 VS 华为 - 抽象工厂模式

    为什么80%的码农都做不了架构师?>>>    抽象工厂模式 简介 定义了一个接口用于创建相关或有依赖关系的对象族,而无明确指定具体的类 组成角色 抽象工厂角色: 这是工厂方法模式的 ...

  7. 【Java设计模式 设计模式与范式】创建型模式 四:抽象工厂模式

    本篇Blog继续学习创建型模式,创建型模式的主要关注点是怎样创建对象,它的主要特点是将对象的创建与使用分离,这样可以降低系统的耦合度,使用者不需要关注对象的创建细节.本篇学习的是抽象工厂模式.由于学习 ...

  8. 看图记设计模式【三】,创建模式系列:抽象工厂模式

    抽象工厂模式 意图 抽象工厂模式是一种创建型设计模式, 它能创建一系列相关的对象, 而无需指定其具体类. 一图说明: 还是老话,请在阅读本篇文章后,记住此图.抽象工厂模式也就记得大半了 图解: 抽象工 ...

  9. 【Python】设计模式(2)--抽象工厂模式

    抽象工厂模式 亦称: Abstract Factory 意图 抽象工厂模式是一种创建型设计模式, 它能创建一系列相关的对象, 而无需指定其具体类. 问题 假设你正在开发一款家具商店模拟器. 你的代码中 ...

最新文章

  1. docker容器网络 - 同一个host下的容器间通信
  2. 一个完整的DS1302时钟在STM32上的应用实例
  3. springboot单元测试中@Autowired自动注入的类一直是null
  4. Nhibernate 基础关系映射
  5. 电影《麦田》的外景地其实是呼伦贝尔
  6. linux下搭建uvm环境,转:使用QuestaSIM进行UVM仿真环境搭建
  7. 10个新鲜出炉的JQuery插件(ITEye)
  8. selenium-滚动
  9. 基于单片机智能药盒控制系统设计(含论文)
  10. BUUCTF REAL
  11. mysql 二次方函数_MySQL SQRT函数:求二次方根
  12. 开源项目9GAG源码解析与Material改造(二)
  13. NYOJ-14-会议安排问题
  14. 苹果手机怎么关闭爱奇艺自动续费_爱奇艺回应涨价为用户创造优质服务,小编建议用户先关闭自动续费...
  15. 单片机什么叫位寻址?/不可位寻址?
  16. win7 怎么修改记事本的默认编码(测试有效果)
  17. 云计算中心怎么选址?
  18. 详解Unicode与UTF-8、UTF-16、UTF-32.
  19. XJTU第八周大计基编程作业
  20. linux命令的使用:配置静态ip,查看网关,dns服务器ip,关闭防火墙,selinux

热门文章

  1. scala 字符串占位符_如何在Scala中将带有换行符的字符串转换为字符串列表?
  2. 你没有见过的 7 种 for 循环优化,超好用!
  3. 从JDK中,我们能学到哪些设计模式?
  4. 表单reset无法重置hidden的解决方案
  5. Android studio小问题解决
  6. 广州海珠区计算机学校,2019广州海珠区电脑派位和对口直升表
  7. 初探EntityFramework——来自数据库的EF设计器
  8. 多多进宝推广团队_多多进宝推广形式及推手寻找、佣金结算方式是怎样的?
  9. 长沙理工大学计算机网络试题,长沙理工大学考试试卷(计算机网络)要点.docx
  10. python字符串迭代_Python字符串迭代/函数