2014-06-28 33 views
4

來自Ruby,我很高興能發現PHP特性。它們類似紅寶石的模塊系統,我喜歡它。使用特徵將大類中的代碼拆分爲多個文件如何?

現在我讀過很多帖子說PHP性狀是邪惡的,因爲他們打破OO設計,可以不容易,你會一類測試它們,等

我想知道如果使用將一個非常大的課程分成更易讀的部分將是一個好主意。

這個班已經很大了,而且可能最終會導致數千條線路沒有重分化。

即使方法可以按照關注分組,但他們經常需要互相調用,這讓我想知道將類分成不同的類是否是最優的。

爲了說明,下面是我提出的一個簡化示例。

大類:

/** 
* Class to refactorize 
*/ 

class Tourist 
{ 
    public function gotoRestaurant() 
    { 

    } 

    public function gotoInternetCafe() 
    { 

    } 

    public function checkEmails() 
    { 

    } 

    public function meetGirlfriend() 
    { 
     if (Girlfriend::location() === 'restaurant') 
     { 
      $this->gotoRestaurant(); 
     } 
     else 
     { 
      $this->checkEmails(); 
     } 
    } 

    public function checkEmailsAndMeetGirlfriend() 
    { 
     $this->checkEmails(); 
     $this->meetGirlfriend(); 
    } 
} 

這裏是我會做,如果使用類重新因式分解:

/** 
* Solution 1: using classes 
*/ 

class ChoreDoer 
{ 
    public function __construct(Tourist $t) 
    { 
     $this->tourist = $t; 
    } 

    public function checkEmails() 
    { 
     $mover = new Mover($this->tourist); 
     $mover->gotoInternetCafe(); 
    } 

    public function meetGirlfriend() 
    { 
     if (Girlfriend::location() === 'restaurant') 
     { 
      $mover = new Mover($this->tourist); 
      $mover->gotoRestaurant(); 
     } 
     else 
     { 
      $this->checkEmails(); 
     } 
    } 
} 

class Mover 
{ 
    public function __construct(Tourist $t) 
    { 
     $this->tourist = $t; 
    } 

    public function gotoRestaurant() 
    { 

    } 

    public function gotoInternetCafe() 
    { 

    } 
} 

class Tourist 
{ 
    public function checkEmailsAndMeetGirlfriend() 
    { 
     $cd = new ChoreDoer($this) 
     $cd->checkEmails(); 
     $cd->meetGirlfriend(); 

    } 
} 

我有一種感覺叫不停new Mover()new ChoreDoer()和即將出現的新課程將變得閱讀和寫作變得痛苦。

那麼在這裏使用特徵來分組功能呢?

/** 
* Solution 2: using traits 
*/ 

trait TouristMovements 
{ 
    public function gotoRestaurant() 
    { 

    } 

    public function gotoInternetCafe() 
    { 

    } 
} 

trait TouristChores 
{ 
    public function meetGirlfriend() 
    { 
     if (Girlfriend::location() === 'restaurant') 
     { 
      $this->gotoRestaurant(); 
     } 
     else 
     { 
      $this->checkEmails(); 
     } 
    } 

    public function checkEmails() 
    { 
     $this->gotoInternetCafe(); 
    } 
} 

class Tourist 
{ 
    use TouristMovements, TouristChores; 
    public function checkEmailsAndMeetGirlfriend() 
    { 
     $this->checkEmails(); 
     $this->meetGirlfriend(); 
    } 
} 

在這裏,每個特質都可以關注其目的,代碼易於閱讀,方法可以自由地互操作。 但是因爲我從來沒有打算在Tourist以外的任何職業中使用TouristsMovements特質,所以我覺得我對他們的使用並不是真正的特質。

你會解決方案1嗎?解決方案2?別的東西?

+0

你有什麼解決方案嗎? –

回答

1

作爲替代方案,你可以做這樣的事情,使用溶液1:

class ChoreDoer 
{ 
    private $mover; 

    public function __construct(Tourist $t) 
    { 
     $this->tourist = $t; 
    } 

    public function checkEmails() 
    { 
     $this->getMover()->gotoInternetCafe(); 
    } 

    public function meetGirlfriend() 
    { 
     if (Girlfriend::location() === 'restaurant') 
     { 
      $this->getMover()->gotoRestaurant(); 
     }else 
     { 
      $this->checkEmails(); 

     } 
    } 
    /** 
    * lazy-load mover object 
    */ 
    private function getMover() 
    { 
     if($this->mover == null) 
     { 
      $this->mover = new Mover($this->tourist); 
     } 
     return $this->mover; 
    } 
} 

如果您使用的getter不喜歡,你可以改爲命名屬性類似

private $_mover; 

,並使用魔法__get打電話給你的getter你:

function __get($property) 
{ 
    $method = 'get'.ucfirst($property); 
    if(method_exists($method)) 
    { 
     return $this->$method(); 
    } 
} 

雖然這不會每形式也相當好,它可以很容易地致電

$this->mover->gotoInternetCafe(); 

而且很好,很乾淨。

相關問題