Design patterns 设计模式以避免在转换/转换期间切换大小写类型
我正在尝试实现一个首选项系统,程序员可以在其中指定首选项名称、类型(布尔、整数、字符串等)以及可选的默认值。我想了一段时间,但没有想到一个通用的解决方案来存储到磁盘或从磁盘加载。我希望设计足够通用,能够处理多种格式(即文本文件、Windows注册表或Apple的属性列表)。简单的解决方案是为每种存储格式制作转换器,并在已经选择了存储格式的情况下在线路的某个位置制作转换器,遍历首选项并在其类型上切换大小写 有人告诉我,在一个类型上执行切换案例不是一个好的解决方案,我明白为什么:如果我添加了一个类型,我需要去修改所有这些切换案例块。那么我应该怎么做呢?通常的答案是让被检查类型的对象实现一个公共接口,并知道如何自己执行操作 但这对我来说似乎很荒谬,因为有一个偏好值知道如何将自己存储在文本文件、Windows注册表和Apple属性列表中。这就解决了问题。如果我添加了一个新的变压器,我需要去修改所有的类型,而不是添加一个新的类型要求我去修改变压器Design patterns 设计模式以避免在转换/转换期间切换大小写类型,design-patterns,Design Patterns,我正在尝试实现一个首选项系统,程序员可以在其中指定首选项名称、类型(布尔、整数、字符串等)以及可选的默认值。我想了一段时间,但没有想到一个通用的解决方案来存储到磁盘或从磁盘加载。我希望设计足够通用,能够处理多种格式(即文本文件、Windows注册表或Apple的属性列表)。简单的解决方案是为每种存储格式制作转换器,并在已经选择了存储格式的情况下在线路的某个位置制作转换器,遍历首选项并在其类型上切换大小写 有人告诉我,在一个类型上执行切换案例不是一个好的解决方案,我明白为什么:如果我添加了一个类型
我想这是一个常见的设计问题,但我找不到任何好的解决方案。访问者模式的经典用法。虽然您有时会看到更一般地表达模式,但下面是一些通过访问者模式表示的持久性层的psuedo代码 请注意,首选项不需要知道如何保存自己,它们只需要将自己传递给存储机制:
abstract BasePreference
{
abstract Persist(PreferenceStorage ps);
}
NumericPreference : BasePreference
{
string Name;
int Value;
int Default
Persist(PreferenceStorage ps)
{
ps.Save(this);
}
}
StringPreference : BasePreference
{
string Name;
string Value;
string Default
Persist(PreferenceStorage ps)
{
ps.Save(this);
}
}
DateRangePreference : BasePreference
{
string Name;
DateTime StartOfRange;
DateTime EndOfRange;
DateTime DefaultStartOfRange;
DateTime DefaultEndOfRange;
Persist(PreferenceStorage ps)
{
ps.Save(this);
}
}
接下来,PreferenceStorage利用方法重载允许为每个pref子类型运行单独的代码。类型上没有开关块:
abstract PreferenceStorage
{
abstract void Save(NumericPreference pref);
abstract void Save(StringPreference pref);
abstract void Save(DateRangePreference pref);
}
最后,PreferenceStorage的子类负责机制或保存数据:
XmlPreferenceStorage : PreferenceStorage
{
void Save(NumericPreference pref)
{
// save number to xml
}
void Save(StringPreference pref)
{
// save string to xml
}
void Save(DateRangePreference pref)
{
// save date range to xml
}
}
RegistryPreferenceStorage : PreferenceStorage
{
void Save(NumericPreference pref)
{
// save number to registry
}
void Save(StringPreference pref)
{
// save string to registry
}
void Save(DateRangePreference pref)
{
// save date range to registry
}
}
(Uggg,为什么格式设置得这么糟糕?很抱歉缩进不好,通常是很好的代码格式设置)现在格式设置看起来更好了…我想这只是个小问题,谢谢。我听说过“访客模式”这个名字,但不知道它的具体内容。这并不是说这个名字能让它跳出来解决这个问题。顺便说一句,Wikipedia动机的例子基本上描述了与我所遇到的问题完全相同的问题。同意,访问者有一个非直观的名称,并且在其通用形式中,所使用的方法名称同样不透明。