设计模式之(一):简单工厂设计模式

本章内容概要:

简单工厂内容概要

一.概念

根据不同的参数返回不同的类的实例

注:简单工厂模式不在GOF四人组所列的23种设计模式之中

二.角色

1.工厂 : 负责创建不同的类的实例
2.抽象产品(接口) : 所有产品类的父类,负责描述产品的公共接口
3.具体产品 : 具体的产品的目标

三.优缺点

1.优点
  • 客户端无须知道创建具体的产品类名,只需知道具体产品对象的参数即可
  • 通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类
2.缺点
  • 由于工厂类集中了所有产品创建逻辑,一旦不能正常工作,可能影响所有产品类
  • 增加新产品时,需要修改工厂类

四.适用场景

  • 创建的对象对象比较少的情况
  • 客户端只知道传入工厂类的参数,对于如何创建对象不关心

五.实例

1.抽象产品
  1. /**
  2. * 电脑(接口)
  3. * @author shixinke
  4. */
  5. public interface Computer {
  6. /**
  7. * 获取电脑的名称(型号)
  8. * @return
  9. */
  10. String getName();
  11. /**
  12. * 获取操作系统名称
  13. * @return
  14. */
  15. String getOsName();
  16. }
2.具体的产品
(1)具体产品1
  1. /**
  2. * 戴尔电脑
  3. * @author shixinke
  4. */
  5. public class DellComputer implements Computer {
  6. public String getName() {
  7. return "戴尔(DELL)";
  8. }
  9. public String getOsName() {
  10. return "Windows 7";
  11. }
  12. }
(2)具体产品2
  1. /**
  2. * mac电脑
  3. * @author shixinke
  4. */
  5. public class MacComputer implements Computer {
  6. public String getName() {
  7. return "Mac 2018";
  8. }
  9. public String getOsName() {
  10. return "Mac OS";
  11. }
  12. }
(3)具体产品3
  1. /**
  2. * thinkPad电脑
  3. * @author shixinke
  4. */
  5. public class ThinkPadComputer implements Computer {
  6. public String getName() {
  7. return "ThinkPad";
  8. }
  9. public String getOsName() {
  10. return "Windows 10";
  11. }
  12. }
3.工厂类
  1. /**
  2. * 电脑工厂
  3. */
  4. public class ComputerFactory {
  5. /**
  6. * 生产电脑的方法
  7. * @param name
  8. * @return
  9. */
  10. public static Computer getComputer(String name) {
  11. if ("Dell".equalsIgnoreCase(name)) {
  12. return new DellComputer();
  13. } else if ("Mac".equalsIgnoreCase(name)) {
  14. return new MacComputer();
  15. } else if ("ThinkPad".equalsIgnoreCase(name)) {
  16. return new ThinkPadComputer();
  17. }
  18. return null;
  19. }
  20. }
4.调用端
  1. /**
  2. * 电脑测试类
  3. * @author shixinke
  4. */
  5. public class ComputerTest {
  6. public static void main(String[] args) {
  7. Computer c1 = ComputerFactory.getComputer("thinkpad");
  8. System.out.println("name = " + c1.getName() + "; os = " + c1.getOsName());
  9. Computer c2 = ComputerFactory.getComputer("mac");
  10. System.out.println("name = " + c2.getName() + "; os = " + c2.getOsName());
  11. Computer c3 = ComputerFactory.getComputer("dell");
  12. System.out.println("name = " + c3.getName() + "; os = " + c3.getOsName());
  13. }
  14. }

以上类的UML关系图:

简单工厂类图

六.源码实例

1.JDK中使用的简单式工厂模式

  1. private static Calendar createCalendar(TimeZone zone,
  2. Locale aLocale)
  3. {
  4. CalendarProvider provider =
  5. LocaleProviderAdapter.getAdapter(CalendarProvider.class, aLocale)
  6. .getCalendarProvider();
  7. if (provider != null) {
  8. try {
  9. return provider.getInstance(zone, aLocale);
  10. } catch (IllegalArgumentException iae) {
  11. }
  12. }
  13. Calendar cal = null;
  14. if (aLocale.hasExtensions()) {
  15. String caltype = aLocale.getUnicodeLocaleType("ca");
  16. if (caltype != null) {
  17. /**
  18. * 通过caltype来确认实例化哪个具体的类
  19. */
  20. switch (caltype) {
  21. case "buddhist":
  22. cal = new BuddhistCalendar(zone, aLocale);
  23. break;
  24. case "japanese":
  25. cal = new JapaneseImperialCalendar(zone, aLocale);
  26. break;
  27. case "gregory":
  28. cal = new GregorianCalendar(zone, aLocale);
  29. break;
  30. }
  31. }
  32. }
  33. if (cal == null) {
  34. if (aLocale.getLanguage() == "th" && aLocale.getCountry() == "TH") {
  35. cal = new BuddhistCalendar(zone, aLocale);
  36. } else if (aLocale.getVariant() == "JP" && aLocale.getLanguage() == "ja"
  37. && aLocale.getCountry() == "JP") {
  38. cal = new JapaneseImperialCalendar(zone, aLocale);
  39. } else {
  40. cal = new GregorianCalendar(zone, aLocale);
  41. }
  42. }
  43. return cal;
  44. }

注:

  • Calendar :可认为是一个抽象产品
  • createCalendar : 简单工厂
  • JapaneseImperialCalendar和GregorianCalenda为具体的产品