我正在建立一个本地化目录并且有一个设计困境。现在,目录存储 aDictionary<string, IString>
来存储翻译,其中IString
可以有两种类型:Singular
或Plural
. 这是一个简化版本IString
:
public interface IString
{
void SetSingular(string singular);
string GetSingular(params object[] args);
void SetPlural(PluralCategory category, string plural);
string GetPlural(PluralCategory category, params object[] args);
}
然后,当我实现 时Singular
,我为复数方法抛出一个NotSupportedException
,它被目录捕获,并且Plural
对单数方法执行相同的操作。
public class Singular : IString
{
// ...
public string GetPlural(PluralCategory category, params object[] args)
{
throw new NotSupportedException(string.Format(
"Singular strings don't support GetPlural({0}, {1})",
category, args));
}
public void SetPlural(PluralCategory category, string plural)
{
throw new NotSupportedException(string.Format(
"Singular strings don't support SetPlural({0}, {1})",
category, plural));
}
}
这种设计源于要求keys对于单数和复数都必须是唯一的,但是我觉得实现不相关的方法和throwNotSupportedException
不好闻。
第二种设计是存储一个Dictionary<string, StringType>
用于密钥检查的,其中StringType
是一个枚举,然后有两个额外的字典Dictionary<string, Singular>
并Dictionary<string, Plural>
根据StringType
. 这使它稍微复杂一点,但不会破坏接口概念。
所以你怎么看?我的第一个想法是不好用NotSupportedException
吗?我应该选择第二种设计还是其他?
编辑:基于@dasblinkenlight 想法的更清晰的解决方案是统一接口方法以获取一个Singular
或Plural
一个单一的。单数只有一个PluralCategory.None
,而复数不允许包含这个类别。这受setter方法的限制,在具体实现定义的接口之外(setter方法不在下面展示)。
public interface IString
{
string GetString(PluralCategory category, params object[] args);
bool HasCategory(PluralCategory category);
}
public class Singular : IString
{
private string Text;
public string GetString(PluralCategory category, params object[] args)
{
if (category == PluralCategory.None)
{
if (Text == null || args == null || args.Length == 0)
{
return Text;
}
return string.Format(Text, args);
}
return null;
}
public bool HasCategory(PluralCategory category)
{
return category == PluralCategory.None;
}
}
public class Plural : IString
{
private Dictionary<PluralCategory, string> Texts = new Dictionary<PluralCategory, string>();
public string GetString(PluralCategory category, params object[] args)
{
string text;
if (Texts.TryGetValue(category, out text))
{
if (text == null || args == null || args.Length == 0)
{
return text;
}
return string.Format(text, args);
}
return null;
}
public bool HasCategory(PluralCategory category)
{
return Texts.ContainsKey(category);
}
}