【问题标题】:It is better to have a caching mechanism inside or outside of a Factory class?在工厂类内部还是外部有缓存机制更好?
【发布时间】:2011-06-20 20:13:47
【问题描述】:

我的问题不是严格的语言相关,它更像是一个通用的编程概念。

如果我有一个具有返回 Parser 对象的方法的 Factory 类,并且我知道这些解析器类不需要在每个迭代周期(当然是在工厂之外)实例化一次以上。

在使用和对象分离方面,为Factory内部的所有实例化的Parsers创建一个缓存机制更好,即:在方法调用期间,或者在它之外,当方法已经被调用时?

提前致谢。

【问题讨论】:

    标签: java design-patterns functional-programming oop


    【解决方案1】:

    我不明白这个问题:工厂类的客户不关心他们收到的对象是否被缓存。所以缓存逻辑必须属于工厂。

    此外,当你实现这个时,你首先实现工厂而不缓存,以便让某些东西快速运行(做最简单的可能工作)。然后,您实现缓存。请注意,做任何其他事情都是过早优化的情况。如果客户端类必须知道对象是否被缓存,那么您的开发过程将很快失败。

    如何实现它取决于您。我喜欢编写一个通用缓存类并在这种情况下重用它,但您可以考虑其他机制。此外,我不做java,因此我不能在这里说明什么更好。

    (PS:我在这个问题的答案中看到了很多设计模式噪音。这在 java 人中是否普遍认为总是在模式方面?这里没有要设计的单例,没有要编写的代理类,只有关于哪个接口不能改变的简单推理)。

    【讨论】:

    • 我已经按照你说的做了,第一个实现没有缓存,我现在引入缓存作为一种优化形式,想知道哪种方法最好。是的,模式思维在 Java 世界中很常见,是四人组塑造了我们所有人,无论幸运与否 :)
    • @Lex:对我来说,设计模式通常要么是你自己想出来的琐碎东西,要么是缺少语言支持的解决方法。滥用模式正在将程序员变成程序。但是,如果您能很好地理解它们何时适用,最重要的是,当它们不适用时,它们可以帮助您提出良好的设计实践。我觉得“java学校”(在法国,最糟糕的编程学校教java,因此我对java的毫无根据的偏见)努力避免让你思考。
    【解决方案2】:

    正如 Shakedown 所说,一种方法是针对接口工作并提供缓存实现和单独的非缓存实现。不过,在某些情况下,这可能会有点麻烦(您的应用真的需要两种不同的实现吗?)。

    如果您有很多这样的类,您可能会考虑使用代理模式。 Proxy 类将实现与 Factory 实现相同的接口,并且仅当从 Factory 返回的对象尚未在 Proxy 的缓存中时才委托给工厂。

    使用动态代理将扩展这种方法,并允许您在任何需要的地方实现缓存,而几乎不需要额外的库膨胀(但以增加复杂性为代价)。

    【讨论】:

      【解决方案3】:

      也许你可以为你的Factory 定义一个接口,然后有多个实现——一个实现可以在内部执行缓存以保证Parser 类只被实例化一次。另一种实现可以不执行缓存,只要有东西需要,就提供新的Parser 对象。

      无论哪种方式,我建议您尝试将此逻辑保留在您的Factory 实现中,并让您的应用程序的其余部分使用Factory 接口。这样,如果您稍后决定不想缓存任何内容或需要更改 Parser 的实例化方式,那么您只有一个对象创建点 - 在 Factory 内。这使得您可以非常轻松地更改构造 Parser 对象的方式,而无需更改应用程序中需要新 Parser 的每个部分。

      再一次 - 如果您创建缓存机制以在 Factory 之外运行,那么这些机制将遍布您的代码,因为您必须在想要获得新的 Parser 时使用它们。如果您稍后决定更改缓存机制,您将不得不接触大量代码,但如果您在 Factory 内部进行缓存,则只需更改 Factory 实现即可。

      【讨论】:

      • @Tom Brito:原理我明白,但是你需要解释一下它是如何应用于这种情况的。
      • 实际上,我已将其发布给任何看到您的答案的人,而不是专门为您。该原则适用于这种情况,因为他询问他的班级是否应该承担比已经承担的更多责任。按照这个原则,答案是否定的,缓存机制应该放在外面,在另一个类中。当然,这将在很大程度上取决于他的项目,但如果他想要遵循一种模式,这可能是一个很好的模式。
      • @Tom Brito 所以你告诉我最好创建一个缓存类并在工厂外保持缓存,而@Shakedown 告诉我相反的情况,你们俩都为此陈述了充分的理由,现在我应该选择...
      • 如果你创建一个caching decorator,你根本不需要改变你的代码......只需用caching decorator 包装你的工厂,当你的代码要求一个新对象时,装饰器会决定它是否从其中的工厂返回旧缓存的一个或一个新的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-28
      • 1970-01-01
      • 1970-01-01
      • 2010-11-15
      • 1970-01-01
      相关资源
      最近更新 更多