0

如果您有多个工厂实现,每个工厂实现都需要不同的状态信息来创建新对象,那么使用哪种模式?

示例: IModelParameters:包含复杂计算的所有输入和输出 IModelParameterFactory:具有获取和保存 IModelParameter 对象的方法。

问题是一个工厂实现可能是从数据库中获取您的参数,需要检索一些状态(即用户ID),另一个可能是从文件中获取您的输入,在这种情况下您没有用户ID,但你确实需要一个文件名。

在这种情况下是否有另一种效果更好的模式?我查看了一些依赖注入工具/库,但没有看到任何似乎可以解决这种情况的东西。

4

3 回答 3

0

您是否尝试将要求放在一个类中?

每个工厂实现都有自己的请求,但所有请求类都派生自一个基本请求类(或实现一个请求接口)。这允许您为所有工厂实现拥有相同的接口,您只需在每个工厂实现中对正确的请求类进行强制转换。

是的,强制转换是丑陋且容易出错的,但是这种方法为您的工厂提供了一个统一的可扩展接口。

于 2013-05-20T19:00:18.860 回答
0

没有看到一些代码很难说,但是您可能想研究实现存储库模式。Repository 实现将负责检索工厂随后用于构建其对象的数据。您可以将存储库接口注入您的工厂:

public class ModelParameterFactory : IModelParameterFactory
{
    private readonly IModelParameterRepository Repository;

    public ModelParameterFactory(IModelParameterRepository repository)
    {
        Repository = repository;
    }

    ...interface methods use the injected repository...
}

然后你会说一个 DatabaseModelParameterRepository 和一个 FileModelParameterRepository。但我猜你也有关于你需要注入哪些的逻辑,所以需要另一个工厂:

public class ModelParameterRepositoryFactory : IModelParameterRepositoryFactory
{
    public ModelParameterRepositoryFactory(...inputs needed to determine which repository to use...)
    {
        ...assign...
    }
    ...determine which repository is required and return it...
}

此时,将 IModelParameterRepositoryFactory 注入 ModelParameterFactory 可能比注入 IModelParameterRepository 更有意义。

public class ModelParameterFactory : IModelParameterFactory
{
    private readonly IModelParameterRepositoryFactory RepositoryFactory;

    public ModelParameterFactory(IModelParameterRepositoryFactory repositoryFactory)
    {
        RepositoryFactory = repositoryFactory;
    }

    ...interface methods get repository from the factory...
}

无论您是否使用 DI 容器,关于使用哪个存储库和使用哪个工厂的所有逻辑现在都被移到相关的工厂实现中,而不是调用代码或 DI 配置。

虽然不是非常复杂,但这种设计确实让我停下来想知道您的 ModelParameterFactory 和 ModelParameters 是否过于通用。您可能会从将它们分成单独的、更具体的类中受益。结果将是一个更简单、更有表现力的设计。但是,如果不是这种情况,上述内容应该对您有用。

于 2013-05-20T20:14:51.443 回答
0

在我看来,状态是你存储在内存中的东西,例如静态对象、全局变量、缓存或会话。通常在 DI 中,这些状态不会被维护,而是作为参数传递。例子:

public IEnumerable<Records> GetRecordByUserId(string userId){ /*code*/ }

正在传递 userId,而不是在存储库中维护。

但是,当您想让它们像配置一样而不是每次查询时都传递时,我认为您可以将其作为包装类注入。有关更多信息,请参阅我的问题。但是,我不推荐在存储库中使用这种设计,但我确实推荐在服务级别。

于 2013-05-21T02:15:55.357 回答