我一直在努力装饰+接口(interface)。说我有以下“行为”界面:
interface IFlyable { void Fly();}
interface ISwimmable { void Swim();}
主界面
interface IMainComponent { void DoSomethingA(); void DoSomethingB();}
主界面上的装饰器
public class Decorator : IMainComponent
{
private readonly IMainComponent decorated;
[..]
public virtual void DoSomethingA()
{
decorated.DoSomethingA();
}
public virtual void DoSomethingB()
{
decorated.DoSomethingB();
}
}
我的问题是如何将装饰对象实现的所有接口(interface)转发给装饰器。一个解决方案是使装饰器实现接口(interface):
public class Decorator : IMainComponent, IFlyable, ISwimmable
{
[..]
public virtual void Fly()
{
((IFlyable)decorated).Fly();
}
public virtual void Swim()
{
((ISwimmable)decorated).Swim();
}
但我不喜欢它,因为:
另一种解决方案是添加“手动转换”以传播装饰树:
public class Decorator : IMainComponent
{
public T GetAs<T>()
where T : class
{
//1. Am I a T ?
if (this is T)
{
return (T)this;
}
//2. Maybe am I a Decorator and thus I can try to resolve to be a T
if (decorated is Decorator)
{
return ((Decorator)decorated).GetAs<T>();
}
//3. Last chance
return this.decorated as T;
}
但是问题是:
您如何解决/解决此问题?有解决此问题的模式吗?
PD:我的问题是最终的C#实现,但是解决方案可能更广泛。
最佳答案
您将需要为每个接口(interface)创建单独的装饰器。一种替代方法是为您的服务和通用装饰器使用通用接口(interface)。例如:
public interface ICommandService<TCommand>
{
Task Execute(TCommand command);
}
public class LoggingCommandService<TCommand> : ICommandService<TCommand>
{
public LoggingCommandService(ICommandService<TCommand> command, ILogger logger)
{
...
}
public async Task Execute(TCommand command)
{
// log
await this.command.Execute(command);
// log
}
}
关于c# - 装饰有几个界面,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55166176/