java - 工厂类

标签 java oop object factory

就我个人而言,我从来没有理解工厂类的概念,因为直接实例化一个 Object 似乎更有用。我的问题很简单,在什么情况下使用工厂类模式是最好的选择,出于什么原因,一个好的工厂类是什么样的?

最佳答案

这是我的代码库中的一个真实的工厂。它用于生成一个采样器类,该类知道如何从某个数据集中采样数据(它最初是在 C# 中,所以请原谅任何 java 错误)

class SamplerFactory
{
  private static Hashtable<SamplingType, ISampler> samplers;

  static
  {
    samplers = new Hashtable<SamplingType, ISampler>();
    samplers.put(SamplingType.Scalar, new ScalarSampler());
    samplers.put(SamplingType.Vector, new VectorSampler());
    samplers.put(SamplingType.Array, new ArraySampler());
  }

  public static ISampler GetSampler(SamplingType samplingType)
  {
    if (!samplers.containsKey(samplingType))
      throw new IllegalArgumentException("Invalid sampling type or sampler not initialized");
    return samplers.get(samplingType);
  }
}

这是一个示例用法:

ISampler sampler = SamplerFactory.GetSampler(SamplingType.Array);
dataSet = sampler.Sample(dataSet);

如你所见,代码并不多,甚至可能更短、更快

ArraySampler sampler = new ArraySampler();
dataSet = sampler.Sample(dataSet);

比使用工厂。那我为什么还要打扰呢?嗯,有两个基本原因,相互依赖:

  1. 首先是代码的简单性和可维护性。假设在调用代码中,enum 作为参数提供。 IE。如果我有需要处理数据的方法,包括采样,我可以写:

    void ProcessData(Object dataSet, SamplingType sampling)
    {
      //do something with data
      ISampler sampler = SamplerFactory.GetSampler(sampling);
      dataSet= sampler.Sample(dataSet);
      //do something other with data
    }
    

    而不是像这样更麻烦的构造:

    void ProcessData(Object dataSet, SamplingType sampling)
    {
      //do something with data
      ISampler sampler;
      switch (sampling) {
        case SamplingType.Scalar:  
          sampler= new ScalarSampler();
          break;
        case SamplingType.Vector:  
          sampler= new VectorSampler();
          break;
        case SamplingType.Array:
          sampler= new ArraySampler();
          break;
        default:
          throw new IllegalArgumentException("Invalid sampling type");
      }
      dataSet= sampler.Sample(dataSet);
      //do something other with data
    }
    

    请注意,每次我需要采样时都应该编写这个怪物。您可以想象,如果我在 ScalarSampler 构造函数中添加了一个参数,或者添加了一个新的 SamplingType,那么进行更改将是多么有趣。而且这个工厂现在只有三个选项,想象一个有 20 个实现的工厂。

  2. 第二,是代码的解耦。当我使用工厂时,调用代码不知道或不需要知道一个名为 ArraySampler 的类甚至存在。该类甚至可以在运行时解析,调用站点也不会更明智。因此,我可以随意更改 ArraySampler 类,包括但不限于直接删除该类,例如我决定 ScalarSampler 也应该用于数组数据。我只需要换行

    samplers.put(SamplingType.Array, new ArraySampler());
    

    samplers.put(SamplingType.Array, new ScalarSampler());
    

    它会神奇地工作。我不必更改调用类中的一行代码,这可能有数百个。实际上,工厂让我可以控制采样发生的内容和方式,并且任何采样更改都有效地封装在与系统其余部分接口(interface)的单个​​工厂类中。

关于java - 工厂类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14575457/

相关文章:

java - 停止具有繁重数据库操作的 Java 线程

javascript - 根据另一个对象中的属性向对象添加属性数组

java - 如何在 Java 循环中和循环外使用 int/double

java - 简单的java,字符串长度

java - 在方法或构造函数之外实例化对象?

java - 如何根据应用程序的体系结构和类正确地组织两个枚举的结构,它们之间存在多对多关系?

javascript - 如何从两个现有对象正确创建一个对象

javascript - 处理 ElasticSearch 中的对象 - 我需要重建它吗?

java - Json 文件到 proto

java - 运行 3 个线程并在 Java 中等待