2015-10-11 36 views
2

在我的應用程序中,我可以在不同的文化背景下有不同的規則。 我有以下代碼。具有條件的PHP類別別的替代邏輯

<?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

我建議你閱讀關於編程的更多的書 - 如THI上http://www.amazon.co.uk/Head-First-Design-Patterns-Freeman/dp/0596007124/ref = sr_1_fkmr0_1?s = books – Danack

回答

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; 

爲什麼要使用一個接口「規則」?有什麼好處?

接口是表示合同義務的一種方式。 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."); 
} 
+0

有趣的實現。兩個問題: 1.爲什麼使用界面「規則」?有什麼好處? 2.解決方案是輝煌的方法,但不是參數(常量,在我的第一個問題)。我想我需要一個更強大和更可靠的方法來管理參數。我認爲必須檢查密鑰的存在是否爲miminum(如果不是,則拋出異常),但是可以使用此設計模式實現變量或常量嗎? 謝謝 –

+0

@MarcelloVerona,我編輯了答案 – Federkun

1

IMO,我會首先創建一個規則接口,這樣的Rules任何child將實現的接口。

interface Rules 
{ 
    //Something here. 
} 

class Rules_IT implements Rules { 

    const MYCONST_1 = 5; 
    const MYCONST_2 = 3; 
    const MYCONST_3 = 10; 

    static public function myMethod(){ 
     return 'Something'; 
    } 
} 

class Rules_DE implements Rules { 

    const MYCONST_1 = 3; 
    const MYCONST_2 = 2; 
    const MYCONST_3 = 15; 

    static public function myMethod(){ 
     return 'Something different'; 
    } 
} 

我看到的大問題是您決定使用哪個類的條件方法。

你可以做的是以下幾點:

$class = 'Rules_' . $pattern; 

if(class_exists($class)) 
{ 
    class_alias($class, 'Rules'); 
}