使用可互换的单例简化调试?

Posted

技术标签:

【中文标题】使用可互换的单例简化调试?【英文标题】:Easing debugging with interchangable singletons? 【发布时间】:2010-10-01 07:26:56 【问题描述】:

我有一些类,例如那些概述数据库表结构或概述应用程序配置的类,它们在整个程序执行过程中根本不会改变状态。我目前将这些类作为单例,希望检索信息的类请求类实例(例如,从常见的 getInstance() 方法),然后继续检索他们想要的信息。虽然这可行,但我希望在配置方面允许更多的模块化,这就是我卡住的地方。

我的主要目标是通过模块化配置更轻松地进行调试,同时仍保持代码的可读性。我不确定我将如何允许交换配置以进行调试,而不包括另一个 Singleton(tm),使用配置设置的类可以从中检索正确的配置实例。

这是针对 php Web 应用程序的,但没有这样标记,因为我猜该解决方案很可能与语言无关。

编辑:为了澄清我的问题,尽管就我的问题的答案而言,依赖注入让我很喜欢,让我提供一个(可能过于简单化的)示例。

假设我有一个 PHP 的 mysqli 类的包装器,它将简单地使用 Config 单例中标识的任何连接信息...

class Mysql 
    // ...
    private $mysqli;

    public function __construct() 
        $conf = Config::getInstance(); // Get the configuration
        $this->mysqli = new Mysqli(
            $conf->getHost(),
            $conf->getUsername(),
            $conf->getPassword()
        );
        // ...
    
    // ...

在这个例子中,Mysql 类将只接受 Config 中包含的设置,并且不能使用除 Config 中包含的配置之外的任何配置。在此示例中,将主机/用户名/密码/其他任何内容简单地传递给构造函数可能更有意义,但随后它落在使用 Mysql 类从 Config 单例中检索它的客户端上,并且问题在许多方面再次表现出来更多课程。由于它最终总是从 Config 中检索依赖项,因此无法通过此设置轻松尝试不同的设置。

从我在几个地方读到的内容,包括这里的精彩 cmets,似乎依赖注入是我最好的选择。对于未来的潜在读者,我找到了一篇关于 PHP 依赖注入的好文章 here,以及对该概念的简化介绍(用 Java 编写)here。

【问题讨论】:

我无法回答您的问题。你能用一个例子来说明你所说的“模块化配置”是什么意思吗? 那里,希望能澄清一点。给出的示例有点过于简单,因为我可以简单地使用不同的数据加载 Config 单例,但在一些更高级的情况下,这种解决方案是不够的。 【参考方案1】:

这是依赖注入的主要规则。这个想法是在运行时注入一个类的实例。在测试期间,您注入具有相同接口的其他东西。它可以是虚拟类、模拟对象或由测试创建的具有预期状态的常规实例。

【讨论】:

以上是关于使用可互换的单例简化调试?的主要内容,如果未能解决你的问题,请参考以下文章

我如何可互换地处理来自 2 个列表的对象

ASCII编码 美国信息互换标准代码

在 SQL 版本之间可互换的 Linq dbml

多个可互换视图 (MFC/C++)

带有可互换字母的字符串

基于可互换出现在两列中的值聚合数据?