Closed. This question is opinion-based。它当前不接受答案。
想改善这个问题吗?更新问题,以便editing this post用事实和引用来回答。
20天前关闭。
我有一个架构问题,我无法独自解决。
我有一系列实现相同接口(IThing)的对象。
我想对“ IThing”集合的每个对象应用转换。
转换取决于接口的实现。
接口实现的转换封装在一个类中。 (策略模式)
我的问题是,在某个地方,我总是以打开类型或一组if-is-cast结束,这对我来说破坏了代码的可扩展性。
这是一个例子:
您是否有任何想法或任何模式名称来解决我的问题?
非常感谢。
然后您可以编写:
这具有编译时安全性的优点:如果添加
如果要稍微抽象一些东西,请将
更一般而言,您可以编写通用访问者:
然后:
想改善这个问题吗?更新问题,以便editing this post用事实和引用来回答。
20天前关闭。
我有一个架构问题,我无法独自解决。
我有一系列实现相同接口(IThing)的对象。
我想对“ IThing”集合的每个对象应用转换。
转换取决于接口的实现。
接口实现的转换封装在一个类中。 (策略模式)
我的问题是,在某个地方,我总是以打开类型或一组if-is-cast结束,这对我来说破坏了代码的可扩展性。
这是一个例子:
public interface IThing
{
string CommonProperty { get; }
}
public class FirstThing : IThing
{
public string CommonProperty { get; }
public string FirstParticularProperty { get; }
}
public class SecondThing : IThing
{
public string CommonProperty { get; }
public string SecondParticularProperty { get; }
}
public interface IThingTransformStrategy<T> where T : IThing
{
string Transform(T thing);
}
public class FirstThingTransformStrategy : IThingTransformStrategy<FirstThing>
{
public string Transform(FirstThing thing)
{
return thing.CommonProperty + thing.FirstParticularProperty;
}
}
public class SecondThingTransformStrategy : IThingTransformStrategy<SecondThing>
{
public string Transform(SecondThing thing)
{
return thing.CommonProperty + thing.SecondParticularProperty;
}
}
public class ThingTransformer
{
private FirstThingTransformStrategy _firstThingTransformStrategy = new FirstThingTransformStrategy();
private SecondThingTransformStrategy _secondThingTransformStrategy = new SecondThingTransformStrategy();
public string TransformThing(IThing thing)
{
//Here is the issue
if (thing is FirstThing) return _firstThingTransformStrategy.Transform((FirstThing) thing);
if (thing is SecondThing) return _secondThingTransformStrategy.Transform((SecondThing) thing);
throw new NotImplementedException();
}
}
您是否有任何想法或任何模式名称来解决我的问题?
非常感谢。
最佳答案
假设您不能修改每个IThing
来知道如何进行自我转换,那么我将介绍访问者模式。
public class ThingTransformer
{
public string Transform(FirstThing thing) => _firstThingTransformStrategy.Transform(thing);
public string Transform(SecondThing thing) => _secondThingTransformStrategy.Transform(thing);
}
public interface IThing
{
// ...
string Transform(ThingTransformer transformer);
}
public class FirstThing : IThing
{
// ...
public string Transform(ThingTransformer transformer) => transformer.Transform(this);
}
public class SecondThing : IThing
{
// ...
public string Transform(ThingTransformer transformer) => transformer.Transform(this);
}
然后您可以编写:
var thing = new FirstThing();
var transformer = new ThingTransformer();
var transformed = thing.Transform(transform);
这具有编译时安全性的优点:如果添加
IThing
的新实现,则最终会出现编译器错误,直到将新方法添加到ThingTransformer
为止。如果要稍微抽象一些东西,请将
ThingTransformer
隐藏在接口后面,并使IThing
采用该接口代替具体的ThingTransformer
。更一般而言,您可以编写通用访问者:
public interface IThingVisitor<T>
{
T Accept(FirstThing thing);
T Accept(SecondThing thing);
}
public interface IThing
{
T Visit<T>(IThingVisitor<T> visitor);
}
public class FirstThing : IThing
{
public T Visit<T>(IThingVisitor<T> visitor) => visitor.Accept(this);
}
public class SecondThing : IThing
{
public T Visit<T>(IThingVisitor<T> visitor) => visitor.Accept(this);
}
public class ThingTransformer : IThingVisitor<string>
{
public string Accept(FirstThing thing) => _firstThingTransformStrategy.Transform(thing);
public string Accept(SecondThing thing) => _secondThingTransformStrategy.Transform(thing);
}
然后:
var thing = new FirstThing();
var transformer = new ThingTransformer();
var transformed = thing.Visit(transformer);
09-27 00:53