我正在尝试实现可以从常规设置继承的本地设置。
一个想法来到我的脑海中使用空值进行设置我想让它从全局设置继承然后将两个设置合并在一起(全局和本地)以获得最终设置
例如:php
$localSettings = ['setting1'=>'value1','setting2=>'value2','setting3'=>null];
//of course the null value will be unsetted
unset($localSettings['setting3']);
$generalSettings = ['setting1'=>'value1','setting2=>'value2','setting3'=>'value3'];
$settings = array_merge($generalSettings ,$localSettings);
任何想法如何使用设计模式实现这种情况?
答案 0 :(得分:2)
我将假设最好将本地和全局设置分开,只在您真正想要访问设置时进行合并。
我想到了两个面向对象的模式,以实现Facade和Composite / Decorator。
使用对两个设置对象的引用构造facade对象,并提供一个简单的界面来获取特定设置。在C ++中:
#include <iostream>
#include <unordered_map>
class Settings {
using SettingsType = std::unordered_map<std::string, std::string>;
private:
const SettingsType* local_;
const SettingsType* global_;
public:
Settings(const SettingsType* local, const SettingsType* global)
: local_(local), global_(global) {}
std::string get(const std::string& key) {
if (local_) {
auto element = local_->find(key);
if (element != local_->end())
return element->second;
}
if (global_) {
auto element = global_->find(key);
if (element != global_->end())
return element->second;
}
return "";
}
};
int main() {
std::unordered_map<std::string, std::string> global_settings;
global_settings["ip"] = "127.0.0.1";
global_settings["port"] = "8080";
std::unordered_map<std::string, std::string> local_settings;
local_settings["hostname"] = "example.com";
local_settings["port"] = "12345"; // Overrride global setting
Settings settings(&global_settings, &local_settings);
std::cout << "ip: " << settings.get("ip") << "\n";
std::cout << "port: " << settings.get("port") << "\n";
std::cout << "hostname: " << settings.get("hostname") << "\n";
}
更灵活的封装解决方案是使用类似于Composite / Decorator模式的东西,并使用全局设置对象组合本地设置对象:
#include <iostream>
#include <unordered_map>
class Settings {
private:
const Settings* parent_settings_;
std::unordered_map<std::string, std::string> settings_;
public:
Settings() : parent_settings_(nullptr) {}
Settings(const Settings* parent) : parent_settings_(parent) {}
void set(const std::string& key, const std::string &value) {
settings_[key] = value;
}
std::string get(const std::string& key) const {
auto found = settings_.find(key);
if (found != settings_.end())
return found->second;
if (parent_settings_)
return parent_settings_->get(key);
return "";
}
};
int main() {
Settings global_settings;
global_settings.set("ip", "127.0.0.1");
global_settings.set("port", "8080");
Settings local_settings(global_settings);
local_settings.set("hostname", "example.com");
local_settings.set("port", "12345"); // Overrride global settings
std::cout << "ip: " << local_settings.get("ip") << "\n";
std::cout << "port: " << local_settings.get("port") << "\n";
std::cout << "hostname: " << local_settings.get("hostname") << "\n";
}
希望有所帮助。