在我的申请中,我可以在不同的文化背景下有不同的规则。 我有以下代码。
<?php
class Rules_IT {
const MYCONST_1 = 5;
const MYCONST_2 = 3;
const MYCONST_3 = 10;
static public function myMethod(){
return 'Something';
}
}
class Rules_DE {
const MYCONST_1 = 3;
const MYCONST_2 = 2;
const MYCONST_3 = 15;
static public function myMethod(){
return 'Something different';
}
}
if($pattern == 'IT'){
class_alias('Rules_'.$pattern, 'Rules');
}
else if($pattern == 'DE'){
class_alias('Rules_'.$pattern, 'Rules');
}
else {
// [...]
}
// And after I use the class Rules ...
print Rules::myMethod();
有效。 我的IDE(NetBeans 7.x)不知道类规则,我不能使用代码自动完成,但不是一个大问题。
但有一些替代方案吗? 逻辑上有一些不同的方法? 一些设计模式来处理这个问题?
谢谢。
答案 0 :(得分:2)
您不需要使用class_alias
或声明静态方法。基础工厂课程可以帮助您。
class RulesFactory
{
/*
public function __construct($validNames = array('IT', 'DE', 'EN')) {
// ...
}*/
public /*static*/ function build($rules_name)
{
$className = "Rules_" . strtoupper($rules_name);
if(class_exists($className)) {
return new $className();
} else {
throw new InvalidArgumentException("Invalid rules name given.");
}
}
}
interface Rules
{
public function myMethod();
public function getParam($name);
}
abstract class AbstractRules implements Rules
{
protected $param = [];
public function getParam($name, $default = null)
{
if (isset($this->param[$name])) {
return $this->param[$name];
} else {
return $default;
}
}
}
class Rules_IT extends AbstractRules
{
protected $param = ['MYCONST_1' => 5, 'MYCONST_2' => 3, 'MYCONST_3' => 10];
public function myMethod()
{
return 'Something';
}
}
class Rules_DE extends AbstractRules
{
protected $param = ['MYCONST_1' => 3, 'MYCONST_2' => 2, 'MYCONST_3' => 15];
public function myMethod()
{
return 'Something different';
}
}
您可以将其用于:
$factory = new RulesFactory();
$rules = $factory->build('IT');
echo $rules->myMethod(), "\n";
echo $rules->getParam('MYCONST_1');
您也可以将RulesFactory::build
声明为静态方法,在这种情况下,您可以将其用作
RulesFactory::build('IT')->myMethod();
<强> MISC:强>
为什么使用getParam
而不是使用常量?
因为它为您提供了一种更灵活的方式来定义和调用这些参数。例如:
abstract class AbstractRules implements Rules
{
protected $param = [];
public function getParam($name)
{
if (isset($this->param[$name])) {
return $this->param[$name];
}
throw new InvalidArgumentException("$name parameter doesn't exists.");
}
public function hasParam($name)
{
return isset($this->param[$name]);
}
public function addParam($name, $value)
{
$this->param[$name] = $value;
}
}
静态属性不与类的任何特定实例/对象相关联,它们属于类本身。你可能不想要这个。但如果你这样做,你可以简单地这样做:
class Rules_IT extends AbstractRules
{
const MYCONST_1 = 5;
const MYCONST_2 = 3;
const MYCONST_3 = 10;
public function myMethod()
{
return 'Something';
}
}
$rules = (new RulesFactory())->build('IT');
echo $rules::MYCONST_1;
为什么要使用界面&#34;规则&#34;?有什么好处?
接口是表示合同义务的一种方式。 Why would I want to use Interfaces?。你已经可以利用这个:
了public function build($rules_name)
{
$className = "Rules_" . ucwords($rules_name);
if(class_exists($className)) {
$object = new $className();
if (!$object instanceof Rules) {
throw new InvalidArgumentException("$className must implement Rules interface");
}
return $object
}
throw new InvalidArgumentException("Invalid rules name given.");
}
答案 1 :(得分:1)
IMO,我首先会创建一个Rules接口,因此任何(RandomA x RandomY)-(RandomB x RandomZ)=one of the aforementioned Range of the "Determinant"
的{{1}}都会实现该接口。
child
我看到的一个大问题是你决定需要使用哪个类的条件方法。
您可以执行以下操作:
Rules
答案 2 :(得分:0)
可能你可以尝试战略模式,特别是如果你的文化规则会很复杂。 https://en.wikipedia.org/wiki/Strategy_pattern