【发布时间】:2015-08-22 04:31:59
【问题描述】:
如何在保持 DRY 状态的同时访问对象中的应用程序设置?
我指的不是数据库凭据或 API 密钥之类的东西,它们保存在环境变量中。我在这里指的设置是这样的:
WORK_DAY_START_TIME 04:00:00
MAX_HOURS_PER_DAY 13
ALLOW_DAY_CROSSOVER false
这些设置会影响业务逻辑,对应用程序来说是全局性的,并且因不同组织而异。目标用户是可能不是技术人员的经理,因此有一个用户界面允许他们更改设置。
这些值被持久化到数据库中(尽管持久性介质在这里无关,因为我可以轻松地从 XML/INI/JSON/YAML 文件中读取)。
这是一个用于访问设置的简单类(它有点多,但就这个问题而言,它就足够了):
<?php
class Settings implements \ArrayAccess
{
private $settings = array();
public function __construct() {
// get settings from DB and put them in $this->settings
}
public function offsetGet($key) {
return $this->settings[$key];
}
}
// In the entry point file:
$settings = new Settings();
检查时我需要值:
class Shift extends EntityObject
{
private function isValid() {
// For illustrative purposes only
return !$settings['ALLOW_DAY_CROSSOVER'] && $this->start < $settings['WORK_DAY_START_TIME'] && $this->end < $settings['WORK_DAY_START_TIME'];
}
}
以下是我想出的一些选项:
-
global $settings或其替代品$GLOBALS['settings']。这依赖于一个全局变量,所以不好。 - 将
Settings设为单例。几乎相同的问题,很难进行单元测试。 - 在每个类的构造函数中,实例化一个
Settings来获取设置。这似乎是一个很大的开销,尤其是当设置已经加载时。 - 将
Settings的实例传递给每个需要设置的对象(基本上是所有对象)的构造函数。如果我理解正确,这听起来像是依赖注入,但它似乎是重复的?
我应该如何解决这个问题?
如果我使用Zend_Config,我想我会遇到同样的问题。
一个相关的问题是$settings array or Config Class to store project settings?。
【问题讨论】:
-
您尝试过 $_SESSION 吗?如果您不想使用 $_SESSION,您始终可以使用返回数组的 php 文件。另一种选择是使用像memcached.org 这样的缓存服务器。没有其他办法
-
我会选择选项 4。根据定义,设置是您的类(或设置中的特定值)的依赖项。除了注入依赖之外,做任何事情都会隐藏这个事实。
标签: php design-patterns configuration