—-慢慢来比较快,虚心学技术—-
**

概念

是一种常用的类创建型设计模式,此模式的核心精神是封装类中变化的部分,提取其中个性化善变的部分为独立类,通过依赖注入以达到解耦、复用和方便后期维护拓展的目的它的核心结构有四个角色,分别是抽象工厂;具体工厂;抽象产品;具体产品

实际上,工厂方法模式是对简单工厂模式的进一步抽象化,

推演

简单工厂例子

  1. /**
  2. * @description 简单工厂模式正例
  3. * @auther:
  4. * @date: 2019-09-25 22:53
  5. */
  6. public class Positive {
  7. public static void main(String[] args) {
  8. /**
  9. * 解决反例中的问题,创建工厂,客户端仅需要知道通过工厂获取具体对象的代号或序号,而不需要知道具体的对象细节
  10. * 即便服务端作者将Hamburger的名字改变了,也仅需要在服务器将1对应的new Hamburger()同步更改,而客户端并不会感知该变化
  11. */
  12. Food food = FoodFactory.getFood(1);
  13. food.eat();
  14. }
  15. }
  16. //======================服务端=======================//
  17. /**
  18. * 简单工厂类,用于生产Food对象
  19. */
  20. class FoodFactory{
  21. public static Food getFood(int n){
  22. Food food = null;
  23. switch (n){
  24. case 1:
  25. food = new Hamburger();
  26. break;
  27. case 2:
  28. food = new Noodle();
  29. break;
  30. }
  31. return food;
  32. }
  33. }
  34. /**
  35. * 接口类,抽象产品
  36. */
  37. interface Food{
  38. void eat();
  39. }
  40. /**
  41. * 实现类,具体产品
  42. */
  43. class Hamburger implements Food {
  44. @Override
  45. public void eat() {
  46. System.out.println("吃汉堡包");
  47. }
  48. }
  49. class Noodle implements Food {
  50. @Override
  51. public void eat() {
  52. System.out.println("吃面条");
  53. }
  54. }

工厂方法例子(用来解决简单工厂弊端的)

  1. /**
  2. * @description 工厂方法模式
  3. * @auther:
  4. * @date: 2019-09-25 22:53
  5. */
  6. public class Positive {
  7. public static void main(String[] args) {
  8. FoodFactory foodFactory = new HamburgerFactory();
  9. Food food = foodFactory.getFood();
  10. food.eat();
  11. }
  12. }
  13. //客户端新扩展一个具体产品
  14. /**
  15. * 具体工厂产品
  16. */
  17. class MyFoodFactory implements FoodFactory{
  18. @Override
  19. public Food getFood() {
  20. return new MyFood();
  21. }
  22. }
  23. class MyNewFood extend Food{
  24. @Override
  25. public void eat() {
  26. System.out.println("我的新食物");
  27. }
  28. }
  29. //======================服务端=======================//
  30. /**
  31. * 抽象工厂接口,替代简单模式的简单工厂类
  32. */
  33. interface FoodFactory{
  34. Food getFood();
  35. }
  36. /**
  37. * 具体工厂产品
  38. */
  39. class HamburgerFactory implements FoodFactory{
  40. @Override
  41. public Food getFood() {
  42. return new Hamburger();
  43. }
  44. }
  45. class NoodleFactory implements FoodFactory{
  46. @Override
  47. public Food getFood() {
  48. return new Noodle();
  49. }
  50. }
  51. /**
  52. * 接口类,抽象产品
  53. */
  54. interface Food{
  55. void eat();
  56. }
  57. /**
  58. * 实现类,具体产品
  59. */
  60. class Hamburger implements Food {
  61. @Override
  62. public void eat() {
  63. System.out.println("吃汉堡包");
  64. }
  65. }
  66. class Noodle implements Food {
  67. @Override
  68. public void eat() {
  69. System.out.println("吃面条");
  70. }
  71. }

应用场景

1、客户端只知道创建产品的工厂名,而不知道具体的产品名
2、创建对象的任务由多个具体子工厂中的某一个完成,而抽象工厂只提供创建产品的接口
3、客户端不关心创建产品的细节,只关心产品的品牌

优点

1、拥有简单工厂的优点,服务端具体产品的细节对客户端并不透明,客户端不需要关注创建对象的部分,去除了与具体产品的依赖
2、当客户端需要扩展一个具体产品时,不需要更改服务端代码,只需要扩展一个新的工厂即可(满足了“开闭原则”)【如上代码中扩展的MyFood产品】

缺点

每添加了一个具体产品,都需要新增一个对应的具体工厂类,增加了代码的复杂度

思考

问题:原本使用简单工厂模式是为了解决客户端与服务端具体产品的耦合问题(服务端产品一旦更改则客户端代码也需要更改),那如今实际上客户端和服务端的工厂具体产品也是紧密耦合的,岂不是又回到了原点?(违反“迪米特法则”)

解答:工厂的名字,是被视为接口的。作者有责任,有义务保证工厂名字的稳定。即业内统一保证工厂名字趋于稳定,至少比具体产品的名字要稳定

如有贻误,还请评论指正