2016-07-04 25 views
-1

我想寫在3層結構中繼承類的東西。這樣的抽象例子。PHP - 類繼承和與另一個類的組合

couriers_list - >快遞 - > COURIER_NAME

class couriers_list { 
    // I'm searches courier_name of the database and reference to the class of courier_name found in database 

    public function show_courier() { 
     return $this->xxx(); 
    } 
} 

class courier extends couriers_list { 
    // Function for the courier 
    // Probably it would interface or abstraction 
} 

class courier_name extends courier { 
    // Methods of accurately courier eg. Calculation associated with the delivery 
    // Here each courier would separate file php eg. ups.php 

    public function xxx() { 
     return 'xxx'; 
    } 
} 

$k = new couriers_list(); 
echo $k->xxx(); 

我不認爲我可以extends快遞courier_list,因爲我沒有訪問方法的後裔。從外部來說,我只想提到couriers_list類,她必須從數據庫中獲取信息,並採用courier_name生成的方法。

如何把這個問題組織對象?

+0

對我來說,這似乎是一個'couriers_list' *包含*'快遞'對象,而'快遞'對象*有一個名字(這可能應該是一個「字符串」!)。你不想爲一個簡單的屬性(如名稱)分別創建類。 – Pete

+0

我編輯了代碼以顯示我的問題。我想從上層的couriers_list之外打電話。從上層類我想執行底層類的操作,我不知道將被稱爲底層類courier_name。 –

+0

我可以使用'$ ks = new courier_name(); return $ ks-> xxx();'在show_courier方法,但我不知道這是一個好主意。 –

回答

0

你的類信使應該是一個接口,因爲它用於定義您的信使應使用

interface CourrierInterface 
{ 
    const CLASS_NAME = __CLASS__; 

    public function getName(); 
    public function getPrices(); 
    public function XXX(); 
    public function calculateDelivery($from, $to); 

    /** these are just example add here all the method that define a courier */ 
} 

然後對於每個信使你有,你應該實現德CourrierInterface

class UpsCourrier implements CourrierInterface 
{ 
    private $name; 

    public function getName() 
    { 
     return $this->name; 
    } 

    public function setName($name) 
    { 
     $this->name = $name; 
    } 

    public function XXX() 
    { 
     // do something 
    } 
} 

我的方式不要以爲CourrierList應該知道數據庫,但只需要包含所有的Courrier對象。 在這裏,我使用的項目

https://github.com/yvoyer/collection

,以管理集合(TypedCollection類),它可以控制你的集合(這裏courrierInterface)中所需類的類型,但你可以使用數組,如果你想它很簡單。

我創建了兩個XXX方法,一個用於特定信使(自列表),另一個用於應用於所有列表。我不知道您的需求,以便採取什麼你需要

class CourrierList 
{ 
    /** 
    * TypedCollection 
    */ 
    private $courrierList; 

    public function __construct() 
    { 
     // i prefer to use a collection class that valid my type instead of an array, your choice! 
     $this->courrierList = new TypedCollection("CourrierInterface"); 
    } 

    public function addCourrier(CourrierInterface $courrier) 
    { 
     $this->courrierList->add($courrier); 
    } 

    public function removeCourrier(CourrierInterface $courrier) 
    { 
     $this->courrierList->removeElement($courrier); 
    } 

    protected function getCourrierByName($courrierName) 
    { 
     $closure = function (CourrierInterface $courrier) use ($courrierName) { 
      return $courrier->getName() == $courrierName; 
     }; 

     return $this->courrierList->filter($closure)->toArray(); 
    } 

    // since its a list, you must be able to select your courrier to execute the XXX() method 
    public function XXXByName($name) 
    { 
     $courrier = $this->getCourrierByName($name); 

     $courrier->XXX(); 
    } 

    // if you prefer to apply to all your courrierList just do 
    public function XXX() 
    { 
     foreach ($this->courrierList as $courrier) { 
      $courrier->XXX(); 
     } 
    } 
} 

因爲我不認爲CourrierList應該知道數據庫中,你可以創建一個工廠,不取在你的數據庫中的數據,並創造一切courriers。這裏dbConnection是你的選擇,pdo等......我只是舉了一個例子,找到了查詢的好方法。

class CourrierListFactory 
{ 

    private $dbConnection; 

    public function __construct(DbConnection $connection) 
    { 
     $this->dbConnection = $connection; 
    } 

    public function createCourrierList() 
    { 
     $results = $this->dbConnection->query(".....")->getResults(); 

     $courrierList = new CourrierList(); 

     foreach ($results as $result) { 
      $courrier = null; 
      switch ($result['name']) { 
       case 'ups': 
        $courrier = new UpsCourrier(); 
        break; 
       case 'fedex': 
        $courrier = new FedexCourrier(); 
        break; 

       /** and so on ... */ 

       default: 
        // maybe throw exception if courier is not handle 
      } 

      $courrier->setName("...."); 
      /** prepare your object here */ 

      // add the courrier to the list 
      $courrierList->addCourrier($courrier); 
     } 

     return $courrierList; 
    } 
} 

最後其如何使用這一切,首先創建的DbConnection,然後建立你的列表中,那麼你就可以存取權限

$dbConnection = new DbConnection(); 

// the factory allows you to separate the database from the List class and may be to generate 
// your list in an other way later (using apis, etc...) 
$factory = new CourrierListFactory($dbConnection); 
$courrierList = $factory->createCourrierList(); 

$courrierList->XXX(); // apply to all 
$courrierList->XXXByName("ups"); // apply just to ups courrier