2010-11-22 59 views
20

在面向對象編程中,自定義類(如具有名稱數據,地址列表等的Person類)保存數據,也可以包含集合對象。數據結構也被用來保存數據。那麼,從概念上講,課程是否考慮了高級數據結構?在設計高效系統(面向對象的世界和大型系統)時,是否將類視爲類似於數據結構和算法分析,以實現高效的類設計以提高效率(在諸如谷歌,臉書等公司中)?類與數據結構

回答

4

自定義類是否是數據結構取決於你問的對象。至少,肯定的人會承認,它比用戶定義的數據結構更具領域性,並且比數據結構(如數組結構,鏈表或二叉樹)要少。對於這個答案,我認爲它們是不同的。

雖然很容易將Big O算法分析應用於數據結構,但它對於類來說更復雜一些,因爲它們包裝了許多這些結構以及其他類的其他實例......但對類進行了大量操作實例可以分解爲對數據結構的基本操作,並以大O的形式表示。作爲一名程序員,您可以通過避免不必要的成員複製並確保方法調用不會經過太多次而努力提高您的類的效率層。當然,在你的方法中使用高性能算法不言而喻,但這不是OOP特定的。但是,除非必要,否則不應犧牲功能,設計和清晰度來提高性能。而過早的優化是惡魔yada yada yada。

我確定有些學者試圖制定一個量化班級績效的指標,甚至是一個班級及其操作的微積分,但我還沒有遇到過。然而,存在像this那樣的質量保證研究,它測量項目中類之間的依賴關係......人們可能會認爲,依賴關係的數量和方法調用的分層之間存在相關性(因此會降低類的性能)。但是如果有人對此進行了研究,我相信你可以找到一個更相關的指標,不需要進行推斷。

6

我會說,概念性一類是NOT的數據結構,一類代表井,一類對象,和對象的抽象(該詞的英語意思,而不是C++或C#含義的詞)實體。

我想說類和對象就像實踐背後的理論,實踐是使用方法和數據實現對象。數據可能簡單或複雜(即所謂的高級數據結構)。

1

類描述一模型/概念/類型,並限定的所述可能的行爲和可能的狀態(在例如,Person可以有一個名字,地址等

一種數據結構是某種類型的可用於組織和組織數據,以某種方式組織和組合數據,例如,向量和鏈接列表是可用於以有序方式存儲數據的數據結構

您可以有一個表示數據的類結構,如C++中的std::vector或Java中的java.util.ArrayList

3

A類只是一組數據和方法,可以處理這些數據。你可以使用一個類來實現一個數據結構,但它們是不同的東西。

以鏈接列表爲例。你可以使用一個類來實現一個Linked List數據結構,並且在某些語言中,這是實現它的最清晰和最明顯的方式。這不是實現鏈接列表的唯一方式,但它可能是最好的,取決於語言。

然而,鏈接列表與作爲一個類沒有任何關係。鏈接列表是一種將數據表示爲獨立節點的方式,其中每個節點以某種方式鏈接到下一個節點。

數據結構是一種數據建模的概念方式,每種不同的數據結構都有不同的屬性和用例。類是一些語言提供的將數據和方法分組的語法方式。

類通常可以用來實現數據結構,但是說一個類==數據結構是不正確的。

+0

任何具有非靜態字段的類都不能實現數據結構嗎?一個只包含字段foo的類會被看作是一個非常簡單的數據結構嗎? – Kelmikra 2015-12-13 23:33:34

19

我建議你閱讀Clean Code第6章:對象和數據結構。整章是關於這個的......如果你不想購買這本書,你可以閱讀摘要,它可以被發現here

據此,你可以以兩種不同的方式有效地使用類。這種現象被稱爲數據/對象反對稱性。根據你的目標,你必須決定你的課程是否遵循open/closed principle
如果他們遵循OCP,他們將是多態,他們的實例將被用作對象。所以他們會隱藏數據和實現一個通用接口,並且很容易添加一個實現該接口的新類型。大多數設計模式都滿足OCP,例如MVC,IoC,每個包裝器,適配器等等......
如果它們不遵循OCP,它們將不會是多形的,它們的實例將用作數據結構。所以他們會公開數據,並且這些數據將被其他類操縱。這也是程序編程的典型方法。有幾個例子不使用OCP,例如DTO的,例外的配置對象,visitor pattern等等

典型模式時,你應該想想履行OCP和代碼移動到一個較低的抽象層次:

class Manipulator { 
    doSomething(Object dataStructure){ 
     if (dataStructure instanceof MyType1){ 
      // doSomething implementation 1 
     } 
     else if (dataStructure instanceof MyType2) 
     { 
      // doSomething implementation 2 
     } 
     // ... 
    }, 
    domSomethingElse(Object dataStructure){ 
     if (dataStructure instanceof MyType1){ 
      // domSomethingElse implementation 1 
     } 
     else if (dataStructure instanceof MyType2) 
     { 
      // domSomethingElse implementation 2 
     } 
     // ... 
    } 
} 

class MyType1 {} 
class MyType2 {} 
//if you want to add a new type, every method of the Manipulator will change 

修復:移動執行到較低的抽象層次和實現OCP

interface MyType { 
    doSomething(); 
    domSomethingElse(); 
} 

class MyType1 implements MyType { 
    doSomething(){ 
     // doSomething implementation 1 
    }, 
    domSomethingElse(){ 
     // domSomethingElse implementation 1 
    } 
} 

class MyType2 implements MyType { 
    doSomething(){ 
     // doSomething implementation 2 
    }, 
    domSomethingElse(){ 
     // domSomethingElse implementation 2 
    } 
} 

// the recently added new type 
class MyType3 implements MyType { 
    doSomething(){ 
     // doSomething implementation 3 
    }, 
    domSomethingElse(){ 
     // domSomethingElse implementation 3 
    } 
} 
時,你應該想想違反OCP和代碼移動到一個更高的抽象水平

典型模式:

interface MyType { 
    doSomething(); 
    domSomethingElse(); 

    //if you want to add a new method here, every class which implements this interface, will be modified 
} 

class MyType1 implements MyType { 
    doSomething(){ 
     // doSomething implementation 1 
    }, 
    domSomethingElse(){ 
     // domSomethingElse implementation 1 
    } 
} 

class MyType2 implements MyType { 
    doSomething(){ 
     // doSomething implementation 2 
    }, 
    domSomethingElse(){ 
     // domSomethingElse implementation 2 
    } 
} 

interface MyType { 
    doSomething(); 
    domSomethingElse(); 
} 

class MyType1 implements MyType { 
    doSomething(){ 
     // doSomething implementation 1 
    }, 
    domSomethingElse(){ 
     // domSomethingElse implementation 1 
    } 
} 

class MyType2 implements MyType { 
    doSomething(){ 
     // doSomething implementation 2 
    }, 
    domSomethingElse(){ 
     // domSomethingElse implementation 2 
    } 
} 

//adding a new type by which one or more of the methods are meaningless 
class MyType3 implements MyType { 
    doSomething(){ 
     throw new Exception("Not implemented, because it does not make any sense."); 
    }, 
    domSomethingElse(){ 
     // domSomethingElse implementation 3 
    } 
} 

修正:移動執行到一個更高的抽象水平和違反OCP

class Manipulator { 
    doSomething(Object dataStructure){ 
     if (dataStructure instanceof MyType1){ 
      // doSomething implementation 1 
     } 
     else if (dataStructure instanceof MyType2) 
     { 
      // doSomething implementation 2 
     } 
     // ... 
    }, 
    domSomethingElse(Object dataStructure){ 
     if (dataStructure instanceof MyType1){ 
      // domSomethingElse implementation 1 
     } 
     else if (dataStructure instanceof MyType2) 
     { 
      // domSomethingElse implementation 2 
     } 
     // ... 
    }, 
    // the recently added new method 
    doAnotherThing(Object dataStructure){ 
     if (dataStructure instanceof MyType1){ 
      // doAnotherThing implementation 1 
     } 
     else if (dataStructure instanceof MyType2) 
     { 
      // doAnotherThing implementation 2 
     } 
     // ... 
    } 
} 

class MyType1 {} 
class MyType2 {} 

或分裂的類成子類。

人們通常遵循OCP的方法計數一或兩個,因爲重複相同的if-else語句不夠乾燥。

我不建議您使用部分滿足的混合類,部分違反OCP,因爲那樣代碼將非常難以維護。你應該根據每種情況來決定你遵循的方法。這通常應該是一個簡單的決定,但是如果你犯了一個錯誤,你以後仍然可以重構你的代碼。

+0

我不知道你是否創建或複製了這個例子,但這是我第一次看到這樣的選擇,我發現它非常有幫助。謝謝。 – Matt 2014-11-19 13:41:56

+0

@Matt這是我的例子,但是在Clean Code中有一個類似的例子。如果我記得好,它有不同的形狀。我仍然不確定SOLID原則,我總是忘記哪個是哪個。 :D SRP和DIP很容易,但其他... – inf3rno 2014-11-19 15:54:22

+0

很好的例子,謝謝。 – 2015-03-03 07:58:51

0

簡單地說,可以看作是由給定的編程語言提供了語法工具,比如Java中,對於在一個程序或應用程序的概念或對象實施中使用的捆綁數據和方法一起。

通過一個類,您可以實現一個軟件組件,它是現實世界中一個想法或對象的表示。您可以通過將對象的屬性作爲成員變量及其行爲或操作捕獲爲類的方法來執行此操作。

另一方面,數據結構基本上是處理數據(數組,鏈接列表,二進制搜索樹)的模型。一個類通常用於實現數據結構,因爲它們以獨特的方式捕獲這些結構的狀態和行爲。

因此,這兩者在這個意義上是截然不同的。