具有条件

时间:2015-10-11 13:01:30

标签: php oop design-patterns

在我的申请中,我可以在不同的文化背景下有不同的规则。 我有以下代码。

<?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)不知道类规则,我不能使用代码自动完成,但不是一个大问题。

但有一些替代方案吗? 逻辑上有一些不同的方法? 一些设计模式来处理这个问题?

谢谢。

3 个答案:

答案 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