工厂方法模式时对简单工厂的进一步抽象化
在简单工厂模式下, 增加功能即意味着必须修改工厂代码。 在《3、简单工厂中》就比如增加了一个手机类, 那我们就必须修改我们的工厂类SimpleFactory来达到功能的升级。在开闭原则下,强调对修改关闭,对扩展开放。 简单工厂显然违背了这一原则,但工厂方法就可以满足开闭原则。其类图如下:
3-1Q114135A2M3.gif

1、场景描述

我们身边有很多品牌的汽车, 每一种汽车都对应有其生产的厂家。 现在我们的汽车与厂家的对应关系如下:

  • 比亚迪汽车—->比亚迪汽车制造商
  • 哈佛汽车 —-> 哈佛汽车制造商

    2、实现

    在这里将工厂与汽车分别抽象如下:
    1. /// <summary>
    2. /// 汽车工厂抽象
    3. /// </summary>
    4. public interface ICarFactory
    5. {
    6. /// <summary>
    7. /// 获取具体汽车
    8. /// </summary>
    9. /// <returns></returns>
    10. ICar GetCar();
    11. }
    12. /// <summary>
    13. /// 比亚迪汽车工厂
    14. /// </summary>
    15. public class BydFactory : ICarFactory
    16. {
    17. public ICar GetCar()
    18. {
    19. return new BydCar();
    20. }
    21. }
    22. // <summary>
    23. /// 哈弗汽车工厂
    24. /// </summary>
    25. public class HavalFactory : ICarFactory
    26. {
    27. public ICar GetCar()
    28. {
    29. return new HavalCar();
    30. }
    31. }
    /// <summary>
    /// 汽车抽象
    /// </summary>
    public interface ICar
    {
      /// <summary>
      /// 展示汽车
      /// </summary>
      void ShowCar();
    }
    /// <summary>
    /// 哈佛汽车
    /// </summary>
    public class HavalCar : ICar
    {
      public void ShowCar()
      {
          Console.WriteLine("哈佛汽车");
      }
    }
    /// <summary>
    /// 比亚迪汽车
    /// </summary>
    public class BydCar : ICar
    {
      public void ShowCar()
      {
          Console.WriteLine("比亚迪汽车");
      }
    }
    
    客户端使用:
    // 比亚迪工厂造比亚迪汽车
    ICarFactory bydFactory = new BydFactory();
    bydFactory.GetCar().ShowCar();
    // 哈佛工厂造哈佛汽车
    ICarFactory havalFactory = new HavalFactory();
    havalFactory.GetCar().ShowCar();
    

    3、优缺点

    工厂方法的优点就如前面所说, 我们增加新的功能的时候, 比如上面增加新的工厂、汽车的时候并不会去修改原有的代码。使用新的功能时,客户端调用相应的工厂即可。但是这也导致了类的数量大量增加,复杂度变得比之前高。相比简单的使用类来说, 多层的抽象其实也导致了系统理解难度的增加。但是这些在我看来都还是小事。 最主要的问题就是一个工厂对应一个产品,其实这局限性有点大了。抽象工厂模式也就是用来解决这个问题的。

    4、应用场景

    客户端不关心具体细节,只关心某个结果。 而且对于这个结果都会对应具体的工厂来实现的时候, 其实就可以考虑工厂方法模式了。