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 - 设置保存位置时,youtube-dl 将 "C:\"转换为 "C#\"

java - 我正在尝试将编辑文本框插入选项卡

java - 在 Java 和 Ubuntu 中从双网卡接收 UDP

javascript - 如何使用对象属性作为函数参数?

c# - 将元素添加到 null(空)List<T> 属性

javascript - Uncaught TypeError : Object. values is not a function JavaScript

java - LibGDX 抗锯齿

python - 类和变量

java - 控制反转和依赖注入(inject)之间的区别

c# - C# 中对象的有效 JSON