【问题标题】:Factory pattern, Avoid same switch case for different interface工厂模式,避免不同接口使用相同的开关盒
【发布时间】:2018-06-19 11:15:08
【问题描述】:

我有一个实现 3 个不同接口的模型

public class CustomerRateSettingModel :  IBaseFactory, IHandleSearch, IHandleSearchAggregate

我对实现设计模式和尝试实现工厂模式来创建实例非常陌生。 但是在编写 Factory 时我无法找到避免相同 Switch 语句的正确方法

  public static IHandleSearch GetClassInstanceForSearch(string className)
    {
        switch (className.ToLower())
        {
            case "customerratesettingmodel":
                return new CustomerRateSettingModel();

            default: return null;
        }
    }

    private static IBaseFactory ManufactureModel(string className)
    {
        switch (className.ToLower())
        {
            case "customerratesettingmodel":
                return new CustomerRateSettingModel();

            default: return null;
        }
    }

是否有任何正确的方法来处理这样的场景?

供参考: 调用工厂的代码

  IHandleSearch instance = ModelFactory.GetClassInstanceForSearch(modelName);


 var modelResult = instance.GetSearch(indexName, searchHistory.SearchParameters);

【问题讨论】:

  • 这不是标准的工厂模式。这看起来像某种依赖注入?工厂模式只会创建对象而不使用字符串来查找对象
  • 我认为你应该研究像 Unity of Simple Injector 这样的 DI 框架
  • @Liam:你是正确的,我应该发送指标而不是类名,但是是的,我正在运行时创建一个具体对象
  • @mjwills :但是必须有一个返回类型,对吧?另一方面,我使用的是具体实例实现的接口函数
  • 我已经成功使用MEF实现工厂stackoverflow.com/questions/26292563/…

标签: c# design-patterns interface factory-pattern


【解决方案1】:

创建Dictionary<string,Func<object>> 以将名称映射到对象制造商。使用as 运算符测试object 是否符合所需的接口:

static readonly IDictionary<string,Func<object>> Makers = new Dictionary<string,Func<object>> {
    ["customerratesettingmodel"] = () => new CustomerRateSettingModel()
};
public static IHandleSearch GetClassInstanceForSearch(string className) {
    return Construct<IHandleSearch>(className);
}
public static IBaseFactory GetClassInstanceForSearch(string className) {
    return Construct<IBaseFactory>(className);
}
private static T Construct<T>(string className) where T : class {
    if (!Makers.TryGetValue(className.ToLower(), out var makeObject) {
        return null;
    }
    return makeObject() as T;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-17
    相关资源
    最近更新 更多