我有一个应用程序(旧版代码)
包含Icomponent
方法的接口save()
以及许多实现它的类。
我想在每次save()之后添加日志。
updae :
我的设计思路很少:
我认为LogService
是singelton的经典案例,但我认为它很难进行单元测试。
使用额外的Icomponent
方法将装饰器模式用于log()
。
创建从每个装饰器的LogService
log()
类
我读了一下这个,但不知道。
是否适用于c#?
UPDATE2
阅读完代码后,我看到还有另一层接口
在混凝土层之前。我不认为我应该装饰每个特定的界面。正确?
I_AComponente : IComponente
I_BComponente : IComponente
A : I_AComponente
B : I_BComponente
答案 0 :(得分:1)
它根本不必是单身人士。考虑:
public void ComponentDecorator : IComponent
{
private IComponent component;
private ILogger logger;
public ComponentDecorator(IComponent component, ILogger logger)
{
this.component = component;
this.logger = logger;
}
public void Save()
{
this.component.Save();
this.logger.Log("Some important message");
}
}
因为无论如何你都会将装饰组件注入装饰器,也可以注入logger(这样很容易测试)。 logger
来自哪里与单元测试的角度无关。
此外,您应该检查现有的记录器,而不是滚动自己的记录器,例如Apache log4net。
修改强>:
单例记录器难以测试的说法可能来自于C#中的单例通常会在某处使用static
字段或静态类实现的事实。说你有:
public static LoggerService
{
public static Log(string message) { ... }
}
现在,在你的装饰者的方法中,你可能需要按照以下方式做点什么:
public void Save()
{
this.component.Save();
LoggerService.Log("Some important message");
}
这使得Save
方法的测试几乎不可能,因为您在方法中具有紧密耦合的依赖关系。如果您可以将LoggerService
配置为不写入文件系统的测试(但仍然是解决问题而不是解决问题),这并不是很糟糕。
在通过接口注入中,问题自然消失了。 LoggerService
可能仍然是静态类,但它可以简单地提供非静态记录器(并管理它们的生命周期/范围)。这根本不会使单元测试变得困难。
答案 1 :(得分:0)
是的! AOP适用于C sharp http://www.developerfusion.com/article/5307/aspect-oriented-programming-using-net/
AOP是避免在代码中编写Log语句的好方法。这是一个如何在您的应用程序中实现AOP的示例....但是,在以下链接中提供的方法的唯一缺点是您还需要配置Castle Windsor http://ayende.com/blog/3474/logging-the-aop-way