2015-07-19 90 views
1

你好我正在尋找一些指導,以選擇一個編程設計模式,以適應我當前的項目。哪種編程設計模式適合這個項目?

我一直在努力尋找一個好的項目,開始正確使用模式,我剛開始的一個小項目似乎提供了一個完美的平臺來學習。

基本上我正在創建一個Telegram Bot來響應用戶的命令。這不是我遇到問題的部分,它是如何最好地構建我的代碼,以便添加新的命令是乾淨的和結構良好的。

我不需要任何人爲我編寫任何代碼,但是有沒有我可以實現的適合的設計模式?

這裏就是我目前在做puesudo(順便說一句,我使用Laravel)代碼:

//routes.php 

    Route::post('inbound', ['uses' => '[email protected]']); 



//inboundController.php 

    public function marshall($inboundMessage){ 

    //Extract the command from the inbound message eg "start" 
    $command = extractfromtext($text); 

    //Get the user id from the person who sent the message 
    $userID = extractIdfromtext($text); 

    //Compare the command in a switch statement 

    switch ($command){ 

    case (start): 
     return $result = new commandStart($userID)->fire(); 
     break; 
    case (demo): 
     return $result = new commandDemo($userID)->fire(); 
     break; 
    case (another): 
     return $result = new commandAnother($userID)->fire(); 
     break; 
    default: 
     break; 

    } 

    } 


//Each command has it's own class: 
//Class commandStart 

    public function __construct($userID){ 
     $this->userID = $userID 
    } 

    publin fuction fire(){ 

    //send a picture to the userID 

    } 



//Class commandDemo 

    public function __construct($userID){ 
     $this->userID = $userID 
    } 

    publin fuction fire(){ 

    //send a message to the userID 

    } 



//Class commandAnother 

    public function __construct($userID){ 
     $this->userID = $userID 
    } 

    publin fuction fire(){ 

    //send a video to the userID 

    } 

這工作得很好,但我覺得

  • 我重複了很多代碼(壞)
  • 添加新命令意味着連續編輯「入站類」文件。我認爲這打破了SOLID中的開放式封閉原則。
  • switch語句給我一個「代碼味道」。

我對所有不同類型的模式的名稱感到非常困惑。有人會建議我,哪一個適合這種情況?我很高興去研究它,以及它是如何實施的,但是我不想因爲我不知道更好而去追逐一個不合適的鵝。

謝謝。


編輯:它似乎在我的嘗試,使這個問題泛型我做得太鈍了。我已經在使用Larvel的MVC。這不是問題我認爲 - 我想知道哪種設計模式可以讓我輕鬆乾淨地添加更多命令 - 希望不必使用switch語句。

在閱讀了一些回覆之後,我想我開始明白該怎麼做。出於興趣 - 下面是建議的實際設計模式還是結構良好的代碼?

+0

你試過MVC(模型 - 視圖 - 控制器)模型嗎? – odedta

+0

使用function_exists()和class_exists(),這樣添加新命令只需要一個帶有fire方法的新類。他們都可以擴展一個抽象類,它可以定義你的共同構造函數並強制孩子實施火法 –

+0

對不起,我不能幫你laravel,我不熟悉它。它被稱爲[抽象工廠設計模式]的設計模式(https://www.google.ro/?gws_rd=cr,ssl&ei=8GurVZWPOcSwsAGjsJS4CA#q=php+abstract+factory+design+pattern) –

回答

0

你在你的代碼中實現的是一個MVC路由器。目前你使用硬代碼路由。相反,您也可以依靠自動加載爲您的控制器實例化選擇正確的類。如果這個類不存在將會使事情變得強健。優勢二:

  • 易於擴展,你只有通過命名約定

  • 添加控制器類名爲文件,你不必在所有觸摸路由器當您添加另一個控制器

你會在網上找到很多關於這方面的例子。自動加載功能也有很好的文檔記錄。

玩得開心!

在什麼arkascha悲傷,我也建議你使用抽象類的命令

abstract class Command { 

    public function __construct($params){ 
     // do some common things with $params 
     $this->do_command(); 
    } 

    protected function do_command(){ 
     // empty function which will be overwritten by child classes 
    } 

} 

和你的子類頂級

2

會像

class FooCommand extends Command { 

    public function __construct($params){ 
     parent::__construct($params); 
     // do something as well 
    } 

    // can be public 
    public function do_command(){ 
     echo __CLASS__, '::FOO'; 
    } 
} 

class BarCommand extends Command { 

    // or without __constructor as mentioned by scrowler if you dont 
    // need to do additional coding with __contructor params 

    // can be protected 
    protected function do_command(){ 
     echo __CLASS__, '::BAR'; 
    } 
} 

class BazCommand extends Command { 

    public function __construct($params){ 
     parent::__construct($params); 
     // do something as well 
    } 

    // it cannot be private 
    private function do_command(){ 
     echo __CLASS__, '::BAZ'; 
    } 
} 
+0

子類沒有需要構造函數。把它放在父母身上會這樣做,所以你不必在子女 –

+0

中定義它們,如果你想用任何方式來處理每個孩子$ params,你可能需要它。在示例中添加了一條評論 –

+0

我建議如果需要做的事情在構造函數中不是標準的,那麼他們會被分解到他們自己的setters和getters中,以保證所有孩子的班級骨骼相同 –

2

請大家看看命令設計模式。您也可以使用之前建議的抽象工廠模式來實例化要執行的命令。

詳細闡述我的答案。 讓我們調用入站控制器我們的客戶端類。控制器的責任是捕獲請求並將其發送到適當的操作,在這種情況下發出命令。 但是,如果您查看代碼,控制器實際上是決定在其接收的某些輸入中實例化基本類型的命令。如果由於某種原因命令類的構造函數發生了變化,那麼您還必須更改入站控制器類中的代碼,因爲它現在還負責實例化要執行的命令對象。 如果你實現一個抽象工廠並注入到你的控制器中,那麼你將必要的輸入傳遞給你的工廠,以決定應該實例化哪一個命令並交給控制器。控制器只是激發它從工廠收到的命令,而不必擔心命令是如何實例化的或它是什麼類型的命令。控制器獲取執行命令的請求,將該命令的實例化委託給工廠,並且一旦該命令由工廠交給控制器執行。 單一責任原則最好。抽象工廠負責實例化命令。控制器負責處理請求,在這種情況下,執行工廠返回的命令。

通過查看代碼,可以看出他正在使用Command設計模式。這裏是來自維基百科的定義:Command design pattern

+0

你能詳細解釋一下這個答案嗎? –

+1

你好@scrowler我在回答中詳細闡述了一點 – Edgar

+0

我非常喜歡用於處理抽象工廠模式輸出的命令設計模式。我可以想象在我的腦海裏。我真的不知道我使用的是命令模式,只是在Laravel文檔中提供了一些示例,這些文檔爲大量命令提供了這種類型的方法,所以我決定運行它! – PilotSnipes

相關問題