6

因为我对 OOP / C# 比较陌生,所以我不知道解决这个问题的正确模式:

我必须为不同的 IO 提供者构建一个插件架构。主机从配置中读取所需的提供者名称/类型,然后应该将提供者实例化并参数化。

所以我基本上有这个接口:

public interface IoProvider //(Base interface, all Providers implements this)
{
    void Initialize();
    void Execute();
}

public interface IFileProvider: IoProvider
{
    string PropertyA { get; set; }
}

public interface ISmtpProvider : IoProvider
{
    string PropertyB { get; set; }
    string PropertyC { get; set; }
}

如您所见,派生的专用 IO 提供程序具有基本接口所没有的不同附加参数属性。为了避免 if/then/else 或 switch 语句,我的想法是使用工厂模式。

但是,如果我正确理解这一点,它并不能解决我的 if/then/else 问题,因为在客户端上我必须检查派生类型以提供正确的参数。

所以主机上的程序流程是这样的:主机读取配置,获取所需提供者的名称/类型主机调用工厂并获取提供者

但是如何避免这种情况——有没有一种模式可以在没有 if/then/else 的情况下解决这个问题?

If (provider == typeOf(IFileProvider))  
PropertyA = value  
else if (provider == typeOf(ISmtpProvider))  
PropertyB = value  
PropertyC = value  
Elseif …
4

3 回答 3

14

您可以switch用多态性替换语句。只允许每个提供者从 config.xml 配置自己。这是一个最佳选择,因为每个提供者都知道要查找哪些值:

provider.Configure();

此方法应存在于基本接口中:

public interface IoProvider 
{
    void Initialize();
    void Execute();
    void Configure();
}

每个提供者都实现它:

public interface ISmtpProvider : IoProvider
{
    string PropertyB { get; set; }
    string PropertyC { get; set; }

    public void Configure()
    {
        PropertyB = ConfigurationManager.AppSettins["B"];
        PropertyB = ConfigurationManager.AppSettins["C"];
    }
}

这种方法的主要好处是您只有一个地方可以更改,当新的提供者添加到您的应用程序时 - 只需添加新的提供者类,它知道如何配置自己。您也不需要更改主机实现。并且您的主机将满足 OCP 原则 - 对扩展开放(您可以添加新提供者),但对修改关闭(添加新提供者时您无需修改​​现有代码)。

您还可以将一些配置对象传递Configure(IConfiguration config)给此方法(它将使您的代码可测试,而不依赖于 static ConfigurationManager)。

于 2012-11-27T16:24:29.607 回答
0

如果您一心想摆脱 if/else 语句,那么您可以在基类中拥有一个加载器,将所有参数传递给该加载器,然后让每个类重载它,并且只使用它们的参数需要。

只有当你的所有派生类都保证使用相同的小参数集合时,我才会认为这是一个理想的模式,只是以不同的方式。否则,if/else语句可能是可取的

于 2012-11-27T16:25:03.463 回答
-2

最后,您总是不得不使用条件语句。

当然,您可以使用一些库来抽象它。例如依赖注入库,并且基于某些构造函数,您可以在没有 if 的情况下执行此操作。

但...

它真的不值得,你会给你的代码增加很多复杂性,只是为了让它更优雅,而且通常不值得权衡。

这并不是说你不能做得更好。从臀部射击,我会在界面中添加这样的方法。

void Init(Dictionary parameters),并在每个实现中从字典中读取并初始化所需的属性

于 2012-11-27T16:25:59.010 回答