可以使用哪些设计模式来构建架构?

时间:2019-11-21 16:56:36

标签: c# design-patterns architecture

我有一个架构问题,我无法独自解决。

  • 我有一系列实现相同接口(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();
    }
}

您有什么想法或任何模式名称来解决我的问题吗?

非常感谢。

3 个答案:

答案 0 :(得分:1)

假设您无法修改每个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);

答案 1 :(得分:0)

为什么要完全使用ThingTransformer?

public interface IThing
{
    string CommonProperty { get; }
    string Transform();
}

public class FirstThing : IThing
{
    public string CommonProperty { get; }
    public string Transform() => this.CommonProperty + this.FirstParticularProperty;

    public string FirstParticularProperty { get; }
}

public class SecondThing : IThing
{
    public string CommonProperty { get; }
    public string Transform() => this.CommonProperty + this.SecondParticularProperty;

    public string SecondParticularProperty { get; }
}

答案 2 :(得分:0)

恕我直言,每个IThing都应该知道如何进行自我转换。为什么在构造IThing时不注入正确类型的IThingTransormStrategy?