【问题标题】:Which 'Design Pattern' is appropriate for a class with a complex (multiple steps) configuration [closed]哪种“设计模式”适合具有复杂(多步骤)配置的类[关闭]
【发布时间】:2013-04-07 15:00:50
【问题描述】:

每当使用安装向导时,用户都会回答许多不同的问题,直到可以开始真正的安装。将此与我当前项目中的一个类进行比较:我有一个需要多个配置步骤的类。它不适用于安装程序,但我认为安装程序向导是解释所需的更大配置功能的好方法。 我正在努力寻找一个好的设计解决方案。

我目前的解决方法:

  1. Flat:我可以定义一个大型类,其中包含所有步骤作为方法/函数/属性。当调用错误的方法时,可以添加一些控制方法来引发异常。它会完成它的工作,但是程序员会因为看到这么多不同的方法而感到困惑。 (-> 他需要更多时间来了解它是如何工作的)

  2. 层次结构:我可以为每个配置步骤创建大约 3 个不同的类。每个都有自己的方法和功能。最后一个类在其构造函数中需要所有 3 个配置类的实例。这看起来不会太混乱,因为每个类中只有正确的方法可见。然而,程序员可能会生气,一个小类需要如此复杂的准备,创建 3 个其他类。也许是嵌套类,但我认为这也是一种糟糕的编码风格。

我想知道是否有人已经遇到过这样的问题,并且可以通过以下方式回答这个问题。要么提供合适的设计模式,要么针对此类问题提供一些经验/最佳实践类结构。

我已经搜索了类似的问题,检查了一些可能适合的设计模式,并且已经提供了 2 种方法思路来说明答案的方向。如果您认为答案不够清楚,请评论/询问遗漏的部分。

【问题讨论】:

  • 问题是可以涉及的设计模式的可能性是无限的,这取决于您的确切要求是什么,确切的领域,我们不知道。您应该找到一个项目,其中有一个阅读源代码的向导。它们通常涉及某种状态模式。
  • 如果一个类有那么多事情要做,这表明已经存在一些设计缺陷。你能详细说明一下这个复杂的引导程序吗?因为如果关注点分离已经存在一些问题,您可能找不到将其转化为好的设计的金锤。
  • @mpm 感谢您的解释。我正在使用 VB.Net/C#,而不是向导的功能,一个类应该易于使用,但是这个类需要多个配置步骤。使用状态模式,我将能够更改相同方法调用的操作,但如果方法在每个步骤中发生更改,那么我想我无法使用它。我在我当前的项目中定义了多个枚举,然后选择从数据库中访问哪一个。一个方法应该提供字符串的结果列表(索引相关)。在此之后,“配置”完成,该类应用作索引查找表
  • @MareInfinitus 我的主要目标是与数据库的通信。由于它需要一个字符串列表(以定义要访问的值)并允许稍后使用 list-index-number 访问这些值,因此我想使用一个简单的枚举。但是,其中一些变量存在 n 次,其中 n 应该在以后为程序员更改。所以我认为我需要构建一个更复杂的配置。 1.step 定义要使用的枚举定义中的参数,2.step 从类中获取字符串列表,3.step 向类询问枚举中的索引,所以我可以在代码中使用枚举

标签: oop class design-patterns coding-style


【解决方案1】:

从问题和 cmets 中的解释来看,“单一班级统治所有人”的方法似乎不是一个好的选择。

也许某种策略模式是要走的路。

您可以根据自己的要求从不同的策略中进行选择,而不是对单个班级进行非常复杂的设置。如果你已经知道那里 将是关于可能发生的三种不同的事情,制定三种不同的策略。

举个例子: 您要写入日志数据。可能是文件、数据库或网络服务。

那么你只有一个对“LogWritting Strategy”的依赖,它有 一个明确定义的接口,让我们说

interface ILogWriter
{
    void Write(enum LogLevel, string logEntry);
}

现在,在您的客户端代码中,您依赖于该接口并仅在该接口上进行调用。但是在运行时,你会根据你的“配置”“注入”一个具体的策略。

即您只需选择适合的策略,并且您没有单个类的复杂引导。

然后你使用具体的策略,比如

IDatabaseLogWriter
IFileLogWriter
IWebServiceLogWriter

可以在此处找到有关策略的简要说明: Strategy pattern

更新

根据最近的评论,我认为存储库和映射模式都可以提供帮助。

你应该考虑看看

Repository pattern, good explanation

Repository explanation by Martin Fowler (top notch architecture)

Metadata mapping

【讨论】:

  • 存储库看起来很有趣。包含 dataMapping 的 Controller 类。但问题是在我的案例中已经存在这样一个额外的数据访问层。它的配置(一个用数字实现的数据映射器总是代表相同的字段)不是那么简单,难以扩展。所以我正在寻找一种模式来使数据映射器的配置更容易。现在,添加一个字段需要我在映射器内的三个不同位置更改代码。因此,我想要一个负责配置的类,并且该类本身应该“易于”更改。
  • 也许你想看看martinfowler.com/eaaCatalog/dataMapper.htmlen.wikipedia.org/wiki/Data_mapper_pattern代码示例包含在第二个链接中
  • 感谢您的建议,我检查了答案,因为您是对的,结构良好的数据映射器不应该有这样的配置问题。但是,我混合使用了工厂模式和构建器模式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 2011-03-18
相关资源
最近更新 更多