【问题标题】:Factory & Strategy patterns工厂和战略模式
【发布时间】:2009-09-30 15:20:47
【问题描述】:

我需要创建一个负责结果集处理的类,但可能会使用不同的算法来处理该结果集。

我知道以下选项:

1) 使用策略模式,下面是伪代码:

interface Strategy {
  processResultSet(ResultSet rs);
}

class StrategyA implements Strategy {
  processResultSet(ResultSet rs);
}

class StrategyB implements Strategy {
  processResultSet(ResultSet rs);
}

Context 类将包含对 Strategy 的引用,并且 Client 应该通过 Strategy 创建 Context 对象的实现,即

class Context {
  private Strategy strategy;

  public Context(Strategy strategy) {
    this.strategy = strategy;
  }

  public doSomething(rs) {
    strategy.processResultSet(rs);
}

问题是我不想将策略对象传递给上下文,但我想创建类似 StrategyFactory 的东西,它将负责创建具体的策略实现。它将客户与战略分开 - 这是一个好的设计吗?

它是 Strategy 和 Factory 的混合体,还是实际上只是 Factory 模式?

【问题讨论】:

  • 如果您将客户端与其策略实现分开,您的工厂(或者可能是抽象工厂)在尝试实例化对象时如何知道要实现哪个策略?
  • 工厂可能不是从客户端获取信息,而是从其他地方(例如配置)获取信息。不知道他的具体实现是不可能的。
  • 两者都是@Alcon 的有效点,但如果我们拥有所有详细信息,则更容易提出明智的建议。
  • 1) 有一个服务 - 单例。 2) 它包含对 DAO 类的引用——它也是一个单例。 3) 在 DAO 中有一个检索 ResultSet 的方法:ResultSet rs = ps.executeQuery();我想在 DAO 中创建一个适当的策略来处理这个结果集。我无法在 DAO 构造函数中传递此策略,因为它特定于传入请求。在构造函数中传递它会使所有传入请求都相同。
  • 所以我决定在 DAO 中创建一个工厂,并在一个方法中创建一个合适的策略(基于请求)并使用它来处理结果集。

标签: java design-patterns oop


【解决方案1】:

这绝对是战略和工厂的结合——但我认为这并不坏。这些模式旨在相互组合和使用。

如果没有在上下文中看到这个设计计划,很难判断这是一个好的设计还是一个坏的设计。仅凭您在此处提供的信息,这两种方式都可以。

看来您的思路是正确的,但让我警告您一句:不要用力过猛,将您的客户与您的策略区分开来。我过去曾这样做过,如果我只允许我的代码的两个部分之间有一点联系,它会导致一个错综复杂的混乱。分离是好的,但努力保持完美的分离可能会导致糟糕的代码和各种问题。

【讨论】:

  • 更准确地说。我有:1)服务类 2)服务类包含对 JDBCDAO 类的引用。 3) JDBCDAO 类包含一个方法:ResultSet rs = ps.executeQuery();我不想将 rs 返回到服务,但让 JDBCDAO 对象处理它并返回一个适当的对象,所以我想创建这个工厂(它创建适当的策略)作为 JDBCDAO 类的成员。
【解决方案2】:

我们已经使用了许多不同的解析场景,它确实有效。我在博客上写了一个代码示例:http://www.herrodius.com/blog/136

我们使用的技巧是给策略接口一个额外的“canProcess”方法,如果策略能够处理数据,它会简单地返回一个布尔值。然后工厂简单地循环遍历所有策略并询问每个策略是否可以处理数据。如果可以,我们会返回该策略或执行该策略。

【讨论】:

    【解决方案3】:

    在您描述的场景中,实际上不需要上下文,而是将其替换为您想要的工厂。在这种情况下,策略模式只是开销和不必要的复杂层。您只需要一个接口或抽象类、实现以及一个工厂或代理来检索实现。

    【讨论】:

    • 如果他使用接口和实现来表示不同的处理算法,根据定义,这就是策略 - 不是吗?
    【解决方案4】:

    与我的想法有关的任何 cmet:

    1) 有一个服务——单例。 2) 它包含对 DAO 类的引用——它也是一个单例。 3) 在 DAO 中有一个检索 ResultSet 的方法:ResultSet rs = ps.executeQuery();我想在 DAO 中创建一个适当的策略来处理这个结果集。我无法在 DAO 构造函数中传递此策略,因为它特定于传入请求。在构造函数中传递它会使所有传入请求都相同。 所以我决定在 DAO(DAO 对象实例)中创建一个工厂,并在一个方法中创建一个合适的策略(基于请求 - 本地对象),并使用它来处理结果集。

    您认为这个解决方案好吗?

    【讨论】:

    • 不,它被过度设计了。只需在您的 DAO 类中实现逻辑,无需工厂或策略。如果您在实现此功能时或之后发现任何通用或样板代码,请务必重构您的代码。但不要犹豫,首先使用一个简单的“如果”。
    • 单例因使代码难以测试而臭名昭著。你考虑过可测试性吗?
    【解决方案5】:

    我认为策略模式应该与工厂模式相结合。在某种程度上,你使用它是绝对正确的。其次,最好将上下文类保留为抽象类,以便可以根据需要扩展不同的上下文。其余的东西看起来不错,但根据你提到的例子,我认为没有必要,但你以正确的方式使用它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      相关资源
      最近更新 更多