gpt4 book ai didi

c# - 了解开闭原则

转载 作者:可可西里 更新时间:2023-11-01 08:36:12 25 4
gpt4 key购买 nike

当我遇到以下代码时,我正在重构一些简单脚本文件解析器的旧代码:

StringReader reader = new StringReader(scriptTextToProcess);
StringBuilder scope = new StringBuilder();
string line = reader.ReadLine();
while (line != null)
{
switch (line[0])
{
case '$':
// Process the entire "line" as a variable,
// i.e. add it to a collection of KeyValuePair.
AddToVariables(line);
break;
case '!':
// Depending of what comes after the '!' character,
// process the entire "scope" and/or the command in "line".
if (line == "!execute")
ExecuteScope(scope);
else if (line.StartsWith("!custom_command"))
RunCustomCommand(line, scope);
else if (line == "!single_line_directive")
ProcessDirective(line);

scope = new StringBuilder();
break;

default:
// No processing directive, i.e. add the "line"
// to the current scope.
scope.Append(line);
break;
}

line = reader.ReadLine();
}

在我看来,这个简单的脚本处理器很适合通过应用“开闭原则”进行重构。以 $ 开头的行可能永远不会被不同地处理。但是,如果需要添加以 ! 开头的新指令怎么办?还是需要新的处理标识符(例如新的 switch-cases)?

问题是,我不知道如何在不破坏 OCP 的情况下轻松、正确地添加更多指令和处理器。 !-case 使用 scope and/or line 让它有点棘手,默认-case.

有什么建议吗?

最佳答案

使用 Dictionary<Char, YourDelegate>指定应如何处理字符。调用DefaultHandler如果字符键在字典中不存在。

添加 Add(char key, YourDelegate handler)允许任何人处理特定字符的方法。

更新

最好使用接口(interface):

/// <summary>
/// Let anyone implement this interface.
/// </summary>
public interface IMyHandler
{
void Process(IProcessContext context, string line);
}

/// <summary>
/// Context information
/// </summary>
public interface IProcessContext
{
}


// Actual parser
public class Parser
{
private Dictionary<char, IMyHandler> _handlers = new Dictionary<char, IMyHandler>();
private IMyHandler _defaultHandler;

public void Add(char controlCharacter, IMyHandler handler)
{
_handlers.Add(controlCharacter, handler);
}

private void Parse(TextReader reader)
{
StringBuilder scope = new StringBuilder();
IProcessContext context = null; // create your context here.

string line = reader.ReadLine();
while (line != null)
{
IMyHandler handler = null;
if (!_handlers.TryGetValue(line[0], out handler))
handler = _defaultHandler;

handler.Process(context, line);


line = reader.ReadLine();
}
}
}

请注意,我传入了一个 TextReader反而。它提供了更大的灵 active ,因为源可以是从简单字符串到复杂流的任何内容。

更新2

我也会分解 !以类似的方式处理。即创建一个处理 IMyHandler 的类:

public interface ICommandHandler
{
void Handle(ICommandContext context, string commandName, string[] arguments);
}

public class CommandService : IMyHandler
{
public void Add(string commandName, ICommandHandler handler)
{
}

public void Handle(IProcessContext context, string line)
{
// first word on the line is the command, all other words are arguments.
// split the string properly

// then find the corrext command handler and invoke it.
// take the result and add it to the `IProcessContext`
}
}

这为处理实际协议(protocol)和添加更多命令提供了更大的灵 active 。您无需更改任何内容即可添加更多功能。因此,关于开放/封闭和其他一些 SOLID 原则,该解决方案是可行的。

关于c# - 了解开闭原则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5416500/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com