可能有效使用单身人士?

时间:2013-04-24 20:43:08

标签: c# design-patterns servicestack

我已经到了设计的重点,我正在认真考虑一个单身人士。

众所周知,“常见”的论点是“永远不要做!这很糟糕!”,好像我们用一堆goto语句填充了我们的代码。

ServiceStack是一个很棒的框架。我自己和我的团队都在其上销售,我们有一个复杂的基于Web服务的基础设施来实现。我一直鼓励异步设计,并在可能的情况下 - 在服务堆栈客户端上使用SendAsync

鉴于我们所有这些不同的系统都做了不同的事情,我想要有一个共同的记录器,(实际上是一个Web服务,如果是Web服务,则会回退到本地文本文件)没有 - 例如一些恶魔正在跟踪建筑物)。虽然我是依赖注入的忠实粉丝,但对于每个异步请求传递对“使用此记录器客户端”的引用似乎并不干净(至少对我而言)。

鉴于ServiceStack的失败签名是Func<TRESPONSE, Exception>(我对此没有任何错误),我甚至不确定如果首先进行调用的封闭方法将具有有效句柄。

但是,如果我们此时有一个单独的记录器,那么<​​em>我们在世界的哪个地方,我们所处的线程以及无数匿名函数的哪一部分无关紧要在。。

这是一个公认的有效案例,还是一个非争论的单身人士?

4 个答案:

答案 0 :(得分:3)

单例的经典实现只有一个问题 - 它易于使用,并引起直接使用,从而导致强耦合, 上帝的对象等。

在经典实现下我的意思是:

class Singleton
{
   public static readonly Singleton Instance = new Singleton();
   private Singleton(){}
   public void Foo(){}
   public void Bar(){}
}

如果仅在对象生命周期策略方面使用单例, 让IoC框架为您管理,保持松耦合 - 拥有一个班级的“一个”实例并没有错 在整个应用期限内,只要确保它是线程安全的。

答案 1 :(得分:3)

日志记录是成为单例的有意义的区域之一,它不应该对您的代码产生任何副作用,并且您几乎总是希望全局使用相同的记录器。使用Singletons时应该关注的主要问题是ThreadSafety,在大多数Logger的情况下,默认情况下它们都是ThreadSafe。

ServiceStack's Logging API允许您通过在App_Start上全局配置它来提供可替代的Logging实现:

LogManager.LogFactory = new Log4NetFactory(configureLog4Net:true);

在此之后,每个班级现在都可以访问上面工厂中定义的Log4Net记录器:

class Any
{
    static ILog log = LogManager.GetLogger(typeof(Any));
}

在所有测试项目中,我更喜欢将所有内容记录到控制台,所以我只需要设置一次:

LogManager.LogFactory = new ConsoleLogFactory();

默认情况下,ServiceStack.Logging会记录到一个忽略每个日志条目的良性NullLogger。

答案 2 :(得分:0)

如果要将通用日志记录放在应用程序代码调用的静态外观后面,请问自己如何实际单元测试该代码。这是Dependency Injection试图解决的问题,但是您通过让应用程序逻辑依赖于静态类来重新引入它。

您可能还有其他两个问题。我问你的问题是:你确定你没有记录太多,并且你确定你没有违反SOLID原则。

我写了SO answer a year back that discusses those two questions。我建议你阅读它。

答案 3 :(得分:0)

与往常一样,我更喜欢有工厂。这样我可以在将来更改实施并维护客户合同。

你可以说单身人士的感情也可能发生变化,但工厂更为普遍。例如,工厂可以实施任意生命周期策略,并根据您的需要随时更改此策略。另一方面,虽然技术上可以为单例实现不同的生命周期策略,但是你所获得的可能不应该被视为“单身”而是“具有特定生命周期策略的单身人士”。这可能和听起来一样糟糕。

每当我使用单身人士时,我首先考虑一个工厂,而且大多数时候,工厂只胜过单身人士。如果你真的不喜欢工厂,那就创建一个静态类 - 一个只有静态方法的无状态类。有可能,你只需要一个对象,只需要一组方法。