2012-07-20 131 views
2

我對分割對象的正確方式有疑問。OOP內聚/耦合混淆

說我有兩個對象,例如工具和技術。一項技術可以有多個與之相關的工具對象,但是它被認爲是一種技術直接瞭解工具的低內聚/緊密耦合?讓Technology對象包含一個Tool對象數組還是應該有某種第三類將它們綁定在一起是不好的做法?

Tool 
private id; 
private title; 

Technology 
private id; 
private title; 
private tools; 

你能提供一個關於如何最好將對象與對象相關聯的簡單概述嗎?乍一看,它似乎對我來說可以,但是對於一個Technology對象來說,添加Tools的getter/setter方法真的適合嗎?

回答

3

如果Technology需要Tool對象,保留它們沒有任何問題。

如果ToolTechnology對象狀態相關,則應該將它們包含在它的內部。

相關的可能的方法:

public addTool(Tool $tool); 
public removeTool(Tool $tool); 
public removeToolByIndex($index); 
public getToolFromIndex($index); 
+0

看到我下面的評論...我不知道這是否有所作爲。 – IOInterrupt 2012-07-20 15:16:29

+0

@IOInterrupt:如果'Technology'不需要工具來工作,但只有幾種方法需要它們,則直接將其注入這些方法:'public function workWithTool(Tool $ tool,$ stuffToDo){' – 2012-07-20 15:19:21

+0

我可能用過可能不好。這與我們現在的模型看起來有點類似。但是,假設我們有一個擁有技術的數據庫模型,每個模型都有多個與之關聯的工具。假設我們有另一個實體,比如Programming,它有許多與它關聯的Technology對象,並且技術將會有許多與之相關的工具。我們並不總是在意與該技術相關的工具,因此我們可能不會將它們包含在查詢中,因此不需要將工具與技術相關聯。 – IOInterrupt 2012-07-20 15:37:12

1

我在沒有辦法對OOP的專家,但我要說的是,這取決於你的域。如果你的域正在處理技術,然後再處理工具,那麼我會說在技術中有一個工具陣列是可以的。我要做的是讓每個工具對象都符合相同的界面,這樣任何技術都可以有任何工具。

另外,從我所瞭解到的情況來看,當你跨越圖層(域,持久性,服務層...)時,我認爲解耦是很重要的。所以一個圖層不應該依賴於另一個圖層,但是你的域對象可以依賴於另一個圖層。

如果你正在建模一個實體依賴於另一個實體的域,那麼這些對象也將相互依賴(如果一個技術沒有它的工具,那麼它就依賴於它們)。以普通的汽車/車輪/駕駛員爲例,汽車在現實世界中都依賴於車輪和駕駛者,所以物體會這樣做,因爲如果他們失蹤,它是完全無用的。

我希望這是有道理的,如果我弄錯了,那麼我也會從別人那裏學到一些東西。

+0

工具絕對是相關的,但在任何時候對象都不需要。有時候某個動作可能需要技術具有工具,而其他時候則不需要將它們關聯起來,因爲我可能真的想要使用該技術,而不關心將工具加載到技術對象中。 – IOInterrupt 2012-07-20 15:14:39

0

您給出的例子是多對多關聯,所以它最好使用3d對象來表示關聯。如果它的途中(一對多),那麼你提到的簡單組合就沒問題。

下面是示例代碼,可以在代碼中進行少許改進 1.實現工具&技術的getter setter,並使變量保持私有狀態。 2.使用接口而不是類直接爲工具&技術。 3.在配對類中使用2個不同的索引(數組)來提高獲取函數的性能,如果不考慮性能,那麼你可以使用一個數組。

<?php 
class Technology{ 
    public $id; 
    public $title; 

    public function __construct($id, $title){ 
     $this->id = $id; 
     $this->title = $title; 
    } 
} 

class Tool{ 
    public $id; 
    public $title; 

    public function __construct($id, $title){ 
     $this->id = $id; 
     $this->title = $title; 
    } 
} 

class TechnologyToolPair{ 
    private $techIndex = array(); 
    private $toolIndex = array(); 

    //Index by id, you can replace title if u maily search by title 
    public function addPair($tech, $tool){ 
     $this->techIndex[$tech->id]['technology'] = $tech; 
     $this->techIndex[$tech->id]['tool'][] = $tool; 

     $this->toolIndex[$tool->id]['tool'] = $tool; 
     $this->toolIndex[$tool->id]['technology'][] = $tech; 
    } 

    public function getByTechnologyId($id){ 
     return $this->techIndex[$id]; 
    } 

    public function getByToolId($id){ 
     return $this->toolIndex[$id]; 
    } 

    public function getByTechnologyName($name){ 
     foreach($this->techIndex as $index => $value){ 
      if(!strcmp($name, $value['technology']->title)){ 
       return $value; 
      } 
     } 
    } 
} 


$tech1 = new Technology(1, 'php'); 
$tech2 = new Technology(2, 'java'); 

$tool1 = new Tool(1, 'eclipse'); 
$tool2 = new Tool(2, 'apache'); 
$tool3 = new Tool(3, 'tomcat'); 

$pair = new TechnologyToolPair(); 
$pair->addPair($tech1, $tool1); 
$pair->addPair($tech1, $tool2); 
$pair->addPair($tech2, $tool1); 
$pair->addPair($tech2, $tool3); 

var_dump($pair->getByToolId(1)); 
var_dump($pair->getByTechnologyId(2)); 
var_dump($pair->getByTechnologyName('java')); 
+0

您的示例使用不贊成使用的語法。從PHP5開始,PHP的結構被命名爲'__construct()'。 – 2012-07-21 07:54:07

+0

改變了,謝謝 – spats 2012-07-22 06:52:35

0

您應該看看工具和技術之間的行爲和交互,而不僅僅是數據。這決定了如何在OOP中建模。您目前正在進行數據建模,並且面向對象應該會提供更好的模塊化。您可能想從測試中推動設計,展示它們的使用方式。