2012-11-19 45 views
0

我有很多東西要學習OO模式,這是我多年來遇到的一個問題。最終,我的課程的唯一目的是程序性的,只是基本上將課程包裝在課堂上。它看起來不像是正確的OO方式去做事情,我想知道是否有人對這個問題有足夠的經驗來幫助我以不同的方式來考慮它。我在當前應用中的具體示例如下。我應該如何命名一個唯一目的是程序性的類?

在我的應用程序中,我從工程測量設備中獲取了一系列要點,並將它們標準化以用於程序中的其他地方。通過「規範化」我的意思是整個數據集的一組轉換,直到達到目標方向。

每個轉換過程將採用點數組(即形式爲class point { float x; float y; float z; })的輸入並返回一個長度相同但數值不同的數組。例如,像point[] RotateXY(point[] inList, float angle)這樣的轉換。另一種程序是分析類型,用於補充規範化過程並決定接下來要做什麼轉換。這種類型的過程使用與參數相同的點,但返回不同類型的數據集。

我的問題是,在這種情況下使用什麼模式?我將要編碼的是一個Normalization類,它繼承了RotationXY的類類型。但RotationXY的唯一目的是旋轉點,所以它基本上將實現一個單一的功能。不過,這似乎不是很好,因爲我在第一段中提到的原因。

在此先感謝!

+1

聲明爲靜態類 – whd

+1

並沒有真正解決這個問題 - 讓我們假設它是一個靜態類,在這種情況下,標準化是,僅僅有過定義的所有程序一個靜態類放置在子命名空間的其他地方。也許我只是在推翻它。 –

回答

3

找到問題域中候選人類的最常見/自然的方法是look for nouns,然後掃描與這些名詞相關的動詞/動作以找出每個類應該實現的行爲。雖然這通常是一個好建議,但這並不意味着你的對象只能代表具體的元素。當進程(通常建模爲方法)開始增長並變得複雜時,將它們建模爲對象是一種很好的做法。所以,如果你的轉型有其自身的重量,它是確定其建模爲一個對象,這樣做:

class RotateXY 
{ 
public function apply(point p) 
{ 
//Apply the transformation 
} 
} 

t = new RotateXY(); 
newPoint = t->apply(oldPoint); 

的情況下,你有很多的轉換,你可以創建一個多態的層次,甚至鏈中的一個轉型之後。如果你想深入挖掘一下,你也可以看看Command的設計模式,與此密切相關。

最後的一些意見:

  • 如果它適合你的情況下,這是一個好主意,在點水平轉換模型,然後將其應用到的點的集合。通過這種方式,您可以正確隔離轉換概念,並且更容易編寫測試用例。如果需要,您甚至可以稍後創建變換的Composite
  • 我一般不喜歡Utils(或類似)班和一幫靜態方法,因爲在大多數的情況下,它意味着你的模型是缺少應隨身攜帶該行爲的抽象。

HTH

+0

非常有幫助,謝謝。這解決了我對靜態類的層次結構的不適,並提供了一些關於命名和模式的好點子。 –

1

通常,當涉及到僅包含靜態方法的類時,我將它們命名爲Util,例如,面向數據庫訪問的DbUtil,面向文件I/O的FileUtil等。因此,找出一些術語,說明所有方法的共同之處,並將其命名爲Util。也許在你的情況下,GeometryUtil或沿着這些線的東西。

+0

謝謝,這有助於瞭解在這種情況下經常使用Util名稱。我會開始做。 –

1

由於您應用的轉換的細節似乎是特定的問題,並可能在未來發生變化,您可以將它們編碼到配置文件中。

該客戶端會從該文件讀取並知道該怎麼做。至於旋轉或其他任何轉換方法,它們都可以作爲Point類的一部分。

+1

謝謝,Jubbat。我將def作爲點類的一部分實現轉換,並沒有考慮做一個配置文件。 –

1

對於基本上只有一個成員的類/接口,我沒有發現任何特別的錯誤。

在你的情況下,該成員是「操作與一些類型返回相同類型的參數」 - 常見的一些數學/功能問題。您可能會發現將接口/基類和幫助器方法組合在一起可以方便地將多個轉換類組合成更復雜的轉換。

另一種方法:如果你的語言支持,它只是去功能風格(類似於C#中的LINQ)。

在實用的風格建議:我先從以下基本功能(可能只是發現他們在語言標準庫)

  • collection = map(collection, perItemFunction)(在C#Select)轉換所有項目的集合在
  • item = reduce (collection, agregateFunction)將所有項目減少爲單個實體(C#中的Aggregate
  • 結合項目funcOnItem = combine(funcFirst, funcSecond)上的2個函數。可以用C#表示爲lambda#Func<T,T> combined = x => second(first(x))
  • 「綁定」/curry - 固定的函數functionOfOneArg = curry(funcOfArgs, fixedFirstArg)的參數之一。可以用C#表示爲lambda Func<T,T> curried = x => funcOfTwoArg(fixedFirstArg, x)

此列表可讓您執行類似於「將X軸上的所有點收集到X軸上並將Y移動15」的操作:map(points, combine(curry(rotateX, 10), curry(shiftY(15)))

的語法將依賴於語言。即在JavaScript中你只是傳遞函數(圖/減少已經是語言的一部分),C# - 拉姆達和Func類(比如對參數的功能 - Func<T,R>)是一種選擇。在某些語言中,你必須明確地使用類/接口來表示一個「函數」對象。

替代做法:如果你實際處理點和改造傳統的另一種方法是使用矩陣來表示所有的線性運算(如果你的語言支持運營商定製你很自然的代碼)。

+1

Alexei:我非常喜歡LINQ的功能風格。你能舉一個例子說明我可以在這裏做什麼嗎?我認爲定義Linq表達式的唯一方法是作爲類的成員內聯。 –

+0

@BrandonArnold,更新了答案... –

相關問題