在工厂实施中处理状态

时间:2013-05-20 18:50:11

标签: interface dependency-injection factory-pattern

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

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

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

在这种情况下,是否有其他模式更好用?我查看了一些依赖注入工具/库,并没有看到任何似乎可以解决这种情况。

3 个答案:

答案 0 :(得分:0)

你有没有试过把这些琐事放在课堂上?

每个工厂实现都有自己的requeriments,但所有requeriments类都派生成一个基础requeriment类(或者强制执行requeriments接口)。这允许您为所有工厂实现提供相同的接口,您只需在每个工厂实现中对正确的requeriments类进行强制转换。

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

答案 1 :(得分: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是否过于通用。您可以从将它们变成单独的,更具体的类中受益。结果将是更简单和更具表现力的设计。但是,如果情况并非如此,上述内容应该适合您。

答案 2 :(得分:0)

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

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

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

但是,当你想让它们像配置一样而不是每次进行查询时,我认为你可以将它作为包装类注入。有关详细信息,请参阅我的question。但是,我不建议在存储库中使用此设计,但我建议在服务级别。