【发布时间】:2020-01-15 07:16:15
【问题描述】:
在不输入学术定义的情况下,假设当您有一个将执行操作的客户端代码(上下文)时使用策略模式,并且该操作可以以不同的方式(算法)实现。例如:https://www.dofactory.com/net/strategy-design-pattern
将使用哪种策略(或算法)取决于某些输入条件的许多场合。这就是策略模式有时与工厂模式结合使用的原因。客户端将输入条件传递给工厂。然后工厂知道必须创建哪个策略。然后Client执行创建的Strategy的操作。
但是,我曾多次遇到一个在我看来恰恰相反的问题。要执行的操作总是相同的,但它只会根据一系列输入条件来执行。例如:
public interface IStrategy
{
string FileType { get; }
bool CanProcess(string text);
}
public class HomeStrategy : IStrategy
{
public string FileType => ".txt";
public bool CanProcess(string text)
{
return text.Contains("house") || text.Contains("flat");
}
}
public class OfficeStrategy : IStrategy
{
public string FileType => ".doc";
public bool CanProcess(string text)
{
return text.Contains("office") || text.Contains("work") || text.Contains("metting");
}
}
public class StragetyFactory
{
private List<IStrategy> _strategies = new List<IStrategy>{ new HomeStrategy(), new OfficeStrategy() };
public IStrategy CreateStrategy(string fileType)
{
return _strategies.Single(s => s.FileType == fileType);
}
}
现在客户端代码将从某个存储库中获取文件并将文件保存在数据库中。就是这个操作,把文件存入数据库,就看文件的类型和每个文件的具体情况了。
public class Client
{
public void Execute()
{
var files = repository.GetFilesFromDisk();
var factory = new StragetyFactory();
foreach (var file in files)
{
var strategy = factory.CreateStrategy(file.Type);
if (strategy.CanProcess(file.ContentText))
{
service.SaveInDatabase(file);
}
}
}
}
我认为这是与策略模式不同的模式是错误的吗? (尽管我在上面的代码中调用了 Strategy ,因为我在好几次看起来都是这样的)
如果这个问题与策略模式解决的问题不同,那么它是哪种模式?
【问题讨论】:
-
这里的策略似乎不能真正互换。文本文件策略不仅对于 docx 文件效率低下,而且无法正常工作。这似乎应该是一个模板类,具有像 C++ 中的 std:: 库这样的实例化。
-
你的工厂只是返回一个基于文件扩展名选择的类的实例。它本质上与 switch 语句相同。不仅如此,如果在同一个
factory上再次调用CreateStrategy,它将返回 same 对象。factory的用户可能会发现这种名为Create的方法有点令人惊讶,并且可能会导致错误。
标签: c# design-patterns strategy-pattern