经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
创建型模式之工厂模式(2.2)
来源:cnblogs  作者:noneplus  时间:2019/8/12 9:14:27  对本文有异议

什么是工厂模式?

工厂模式是创建型模式的一种,工厂是用来生产的,而在Java里,是用来生产对象实例的。


和单例模式相似,工厂模式同样聚焦于在考虑整个软件构建的情况下合理创建对象,从而保证软件的扩展性和稳定性。

工厂模式分为三种:

  • 简单工厂模式
  • 工厂方法模式
  • 抽象工厂模式

简单工厂模式(实现服务端自扩展)

服务端:提供代码的人(作者)

客户端:使用代码的人(用户)

【对于程序员来说,自己是作者,用户是普通人;那么对于发明语言,框架的人来说,创建者是作者,而普通程序员是用户】

假设没有使用简单工厂模式:

定义一个Coder接口,然后定义JavaCoder和PythonCoder实现Coder接口。客户端通过new来创建对象。(耦合)

  1. //服务端
  2. interface Coder {
  3. void express();
  4. }
  5. class JavaCoder implements Coder
  6. {
  7. @Override
  8. public void express()
  9. {
  10. System.out.println("I am a Java Coder");
  11. }
  12. }
  13. class PythonCoder implements Coder
  14. {
  15. @Override
  16. public void express()
  17. {
  18. System.out.println("I am a Python Coder");
  19. }
  20. }
  21. //===============================================================================
  22. public class ProductManager //客户端
  23. {
  24. public static void main(String[] args) {
  25. Coder javaCoder = new JavaCoder();
  26. javaCoder.express();
  27. }
  28. }

当服务端需要扩展一个类时:需要进行1,2两步

  1. //服务端
  2. interface Coder {
  3. void express();
  4. }
  5. class JavaCoder implements Coder
  6. {
  7. @Override
  8. public void express()
  9. {
  10. System.out.println("I am a Java Coder");
  11. }
  12. }
  13. class PythonCoder implements Coder
  14. {
  15. @Override
  16. public void express()
  17. {
  18. System.out.println("I am a Python Coder");
  19. }
  20. }
  21. class GoCoder implements Coder //1.服务端扩展
  22. {
  23. @Override
  24. public void express()
  25. {
  26. System.out.println("I am a Go Coder");
  27. }
  28. }
  29. //===============================================================================
  30. public class ProductManager //客户端
  31. {
  32. public static void main(String[] args) {
  33. Coder javaCoder = new JavaCoder();
  34. javaCoder.express();
  35. Coder goCoder = new GoCoder(); //2.客户端跟着修改
  36. goCoder.express();
  37. }
  38. }

服务端和客户端处于高度耦合状态。(服务端的变化会引起客户端的变化)

使用简单工厂模式:(如果服务端要扩展一个GoCoder,客户端无需做修改)

  1. //服务端
  2. interface Coder {
  3. void express();
  4. }
  5. class JavaCoder implements Coder
  6. {
  7. @Override
  8. public void express()
  9. {
  10. System.out.println("I am a Java Coder");
  11. }
  12. }
  13. class PythonCoder implements Coder
  14. {
  15. @Override
  16. public void express()
  17. {
  18. System.out.println("I am a Python Coder");
  19. }
  20. }
  21. class GoCoder implements Coder //1.服务端扩展
  22. {
  23. @Override
  24. public void express()
  25. {
  26. System.out.println("I am a Go Coder");
  27. }
  28. }
  29. class SimpleFactory
  30. {
  31. //使用静态内部类实现单例模式
  32. private static class StaticClassInnerInstance {
  33. private static final SimpleFactory INSTANCE = new SimpleFactory();
  34. }
  35. public static SimpleFactory getInstance() {
  36. return StaticClassInnerInstance.INSTANCE;
  37. }
  38. public Coder createCoder(String language)
  39. {
  40. Coder coder = null;
  41. if(language.equals("Java"))
  42. {
  43. coder= new JavaCoder();
  44. }
  45. else if(language.equals("Python"))
  46. {
  47. coder= new PythonCoder();
  48. }
  49. else if(language.equals("Go")) //2.扩展条件
  50. {
  51. coder= new GoCoder();
  52. }
  53. return coder;
  54. }
  55. }
  56. //===============================================================================
  57. public class ProductManager //客户端
  58. {
  59. public static void main(String[] args) {
  60. SimpleFactory factory = SimpleFactory.getInstance();
  61. Coder javaCoder = factory.createCoder("Java");
  62. javaCoder.express();
  63. }
  64. }

简单工厂UML类图:

1565531609458

简单工厂的优缺点:

优点:

解决了服务端与客户端的耦合问题,实现了服务端的自扩展。

缺点:

当客户端需要进行功能扩展时,无法在SimpleFactory中添加对应修改代码。

简单工厂可以完成服务端的自扩展,但客户端只能调用,无法扩展。

工厂方法模式(实现客户端自扩展)

  1. //服务端
  2. interface Coder {
  3. void express();
  4. }
  5. class JavaCoder implements Coder
  6. {
  7. @Override
  8. public void express()
  9. {
  10. System.out.println("I am a Java Coder");
  11. }
  12. }
  13. class PythonCoder implements Coder
  14. {
  15. @Override
  16. public void express()
  17. {
  18. System.out.println("I am a Python Coder");
  19. }
  20. }
  21. class GoCoder implements Coder //1.服务端扩展
  22. {
  23. @Override
  24. public void express()
  25. {
  26. System.out.println("I am a Go Coder");
  27. }
  28. }
  29. interface CoderFactory //抽象出CoderFactory
  30. {
  31. public Coder createCoder(String language);
  32. }
  33. class ServerFactory implements CoderFactory
  34. {
  35. private static class StaticClassInnerInstance {
  36. private static final ServerFactory INSTANCE = new ServerFactory();
  37. }
  38. public static ServerFactory getInstance() {
  39. return StaticClassInnerInstance.INSTANCE;
  40. }
  41. @Override
  42. public Coder createCoder(String language)
  43. {
  44. Coder coder = null;
  45. if(language.equals("Java"))
  46. {
  47. coder= new JavaCoder();
  48. }
  49. else if(language.equals("Python"))
  50. {
  51. coder= new PythonCoder();
  52. }
  53. else if(language.equals("Go")) //2.扩展条件
  54. {
  55. coder= new GoCoder();
  56. }
  57. return coder;
  58. }
  59. }
  60. //===============================================================================
  61. class RustCoder implements Coder
  62. {
  63. @Override
  64. public void express()
  65. {
  66. System.out.println("I am a Rust Coder");
  67. }
  68. }
  69. class ClientFactory implements CoderFactory
  70. {
  71. private static class StaticClassInnerInstance1 {
  72. private static final ClientFactory INSTANCE = new ClientFactory();
  73. }
  74. public static ClientFactory getInstance() {
  75. return ClientFactory.StaticClassInnerInstance1.INSTANCE;
  76. }
  77. @Override
  78. public Coder createCoder(String language)
  79. {
  80. return new RustCoder();
  81. }
  82. }
  83. public class ProductManager //客户端
  84. {
  85. public static void main(String[] args) {
  86. ClientFactory clientFactory = ClientFactory.getInstance();
  87. Coder coder = clientFactory.createCoder("Rust");
  88. coder.express();
  89. }
  90. }

工厂方法UML类图:

1565532368140

工厂方法模式的优缺点:

优点:实现了客户端的自扩展。

缺点:无法扩展多个产品。

抽象工厂模式(实现产品簇)

适应多个产品,加入设计师。

抽象工厂中可以生产多个产品,产品之间存在内在联系。比如说JavaCoder对应JavaDesigner。

而实例化的工厂就是根据这种内在联系来划分的。

同一个工厂的产品属于一个产品簇,不同产品簇之间是不能互相组合的。比如说GoDesigner和PythonCoder是不能组合到一个工厂里的。

  1. //服务端
  2. interface Coder {
  3. void express();
  4. }
  5. interface Designer {
  6. void express();
  7. }
  8. class JavaCoder implements Coder
  9. {
  10. @Override
  11. public void express()
  12. {
  13. System.out.println("I am a Java Coder");
  14. }
  15. }
  16. class PythonCoder implements Coder
  17. {
  18. @Override
  19. public void express()
  20. {
  21. System.out.println("I am a Python Coder");
  22. }
  23. }
  24. class GoCoder implements Coder
  25. {
  26. @Override
  27. public void express()
  28. {
  29. System.out.println("I am a Go Coder");
  30. }
  31. }
  32. class JavaDesigner implements Designer
  33. {
  34. @Override
  35. public void express()
  36. {
  37. System.out.println("I am a Java Designer!");
  38. }
  39. }
  40. class PythonDesigner implements Designer
  41. {
  42. @Override
  43. public void express()
  44. {
  45. System.out.println("I am a Python Designer!");
  46. }
  47. }
  48. class GoDesigner implements Designer
  49. {
  50. @Override
  51. public void express()
  52. {
  53. System.out.println("I am a Go Designer!");
  54. }
  55. }
  56. interface ProductFactory
  57. {
  58. public Coder createCoder();
  59. public Designer createDesigner();
  60. }
  61. class GoFactory implements ProductFactory
  62. {
  63. private static class StaticClassInnerInstance {
  64. private static final GoFactory INSTANCE = new GoFactory();
  65. }
  66. public static GoFactory getInstance() {
  67. return StaticClassInnerInstance.INSTANCE;
  68. }
  69. @Override
  70. public Coder createCoder()
  71. {
  72. Coder coder= new GoCoder();
  73. return coder;
  74. }
  75. @Override
  76. public Designer createDesigner()
  77. {
  78. Designer designer= new GoDesigner();
  79. return designer;
  80. }
  81. }
  82. class JavaFactory implements ProductFactory
  83. {
  84. private static class StaticClassInnerInstance {
  85. private static final JavaFactory INSTANCE = new JavaFactory();
  86. }
  87. public static JavaFactory getInstance() {
  88. return StaticClassInnerInstance.INSTANCE;
  89. }
  90. @Override
  91. public Coder createCoder()
  92. {
  93. Coder coder= new JavaCoder();
  94. return coder;
  95. }
  96. @Override
  97. public Designer createDesigner()
  98. {
  99. Designer designer= new JavaDesigner();
  100. return designer;
  101. }
  102. }
  103. //===============================================================================
  104. public class ProductManager //客户端
  105. {
  106. public static void main(String[] args) {
  107. JavaFactory javaFactory = JavaFactory.getInstance();
  108. Coder coder =javaFactory.createCoder();
  109. Designer designer = javaFactory.createDesigner();
  110. coder.express();
  111. designer.express();
  112. }
  113. }

抽象工厂UML类图:

1565533010264

工厂模式总结

简单工厂模式:适用客户端无需扩展的应用场景

工厂方法模式:适合客户端创建单个产品的应用场景

抽象工厂模式:适合创建多个产品的应用场景(但产品类别需要固定)

-------------------------------------------------------------------------------------------------------------2019.8.11

原文链接:http://www.cnblogs.com/noneplus/p/11337158.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号