Создай объект конфигурации у которого не будет системы кэширования и передовай его в объект кэша. Настроеный объект кэша, передай уже в конфигурацию, которая работает с кэшем. То есть настройки кэша у тебя не будут кэшироваться, и будут настраиваться отдельно от все конфигурации.
interface Configuration
{
}
abstract class AbstractConfiguration extends Configuration
{
public $cache;
abstract public function get($name);
}
class ConfigurationCached extends AbstractConfiguration
{
public function get($name)
{
$value = $this->cache->get($name);
if (!is_null($value)) {
return $value;
}
return $this->load($name);
}
}
class ConfigurationWithoutCached extends AbstractConfiguration
{
public function get($name)
{
return $this->load($name);
}
}
class Cache
{
public $configuration;
public function get($name)
{
$this->tryInit();
return $this->fetch($name);
}
protected function tryInit()
{
}
}
$cache = new Cache;
$config = new ConfigurationWithoutCached;
$cache->configuration = $config;
$config2 = new ConfigurationCached;
$config2->cache = $cache;
Эту проблему нельзя обойти путем умного определения на то что мы вошли в рекурсию, так как это приведет к тому что объекты будут знать о друг о друге слишком много и о том как они работают. Потому лучше сделать вот такую вот подмену.
То есть, если сделать вот так, то это будет не правильно
class ConfigurationCached extends AbstractConfiguration
{
public function get($name, $useCache = true)
{
if ($useCache) {
$value = $this->cache->get($name);
if (!is_null($value)) {
return $value;
}
}
return $this->load($name);
}
}
$config = new ConfigurationWithoutCached;
$config->get('ip_cache', false);
Так как аргумент $useCache очень конкретно показывает нам, что внутри есть кэш и он явно влияет на отдаваемый результат, что в свою очередь нарушает принцип ООП - инкапсуляция.
_____________
Люди, имеющие низкий уровень квалификации, делают ошибочные выводы, принимают неудачные решения и при этом неспособны осознавать свои ошибки в силу низкого уровня своей квалификации