2012-01-06 124 views
3

我有3個不同類型的形狀圖表說RectangleCubeCircle,我想爲它們定義,使得面向對象設計/設計模式的情況下

  • 所有類的類將有標題& Color屬性/方法,

  • 圈&矩形將有更多的方法區,

  • 同樣竟被魔方d有Volume方法而不是Area方法。

有我在其中得到「對象」的參考方法,下面是示例方法

public void ShapeClicked(object obj) 
{ 
// Check the type of obj & type cast it accordingly & call the method on that object 
    object obj = new Circle(); 

    if (obj is Circle) 
    { 
     Circle circleObj = (Circle)obj; 
     circleObj.GetArea(); 
    } 
    else if (obj is Rectangle) 
    { 
     Rectangle rectangleObj = (Rectangle)obj; 
     rectangleObj.GetArea(); 
    } 
    else if (obj is Cube) 
    { 
     Cube cubeObj = (Cube)obj; 
     cubeObj.GetVolume(); 
    } 
} 

我如何設計我的班,使得「ShapeClicked(obj對象)」方法

  • 一)我不必每次檢查的類型(應該在運行時發生),(這對我來說很重要,因爲我有很多方法,如「ShapeCli cked」這需要我覈對型號)

  • B)如果對象是圓的話,那就只能得到區域的方法,同樣的立方體對象,將只能得到體積法。

我能想到的把所有的方法在基類&在派生類才覆蓋所需的方法&性質兩種方法

  • 。創建一個工廠方法/類,它將返回基類的引用。通過這種方法,我的'b'要求不符合

  • 僅在基類&中添加常用方法/屬性(如顏色),以便在派生類中添加其他方法。這並不能解決#A :(

可有人建議我一些解決方案,解決了這兩個#A#B &

+0

這是真正的代碼還是隻是一個任意的樣本?現在你的示例是從形狀中獲取一個數字,但是你沒有顯示你用它做了什麼。 – tcarvin 2012-01-06 14:00:39

回答

3

介紹一個新的界面。

public interface IMeasurable 
{ 
    someReturnType GetMeasure(); 
} 

public class Circle : IMeasurable 
{ 
    //some other methods 

    public someReturnType GetMeasure() { return GetArea(); } 
} 

public class Cube : IMeasurable 
{ 
    //some other methods 

    public someReturnType GetMeasure() { return GetVolume(); } 
} 

更新

你的方法看起來像:

public void ShapeClicked(object obj) 
{ 
    var measurable = obj as IMeasurable; 
    if (measurable == null) 
     throw new InvalidOperationException(string.Format("We can only work with measurable types, which {0} is not.", obj.GetType()); 

    var measure = measurable.GetMeasure(); 
} 
+0

感謝您的迴應,您已將'GetMeasure'方法添加到cicle和cube,並從那裏調用其各自的方法。我有很多像GetVolume/GetArea一樣的方法,一些對於圓,多維數據集和其餘部分都是特定於該類的。如何解決我在問題中提到的#a&#b? – 2012-01-08 01:35:31

+0

在基類中實現不可測量性。 – jgauffin 2012-01-08 11:25:55

+0

你能否回答http://stackoverflow.com/questions/9511137/is-the-solution-design-optimal-c-sharp-3-tier? – Lijo 2012-03-01 05:42:27

0

是。

你應該有各種形狀的基類和具有在基類的方法ShapeClicked()

class Shape 
{ 
-tile 
-color 
ShapeClicked() 
} 

class PlanarShape extends Shape 
{ 
-area 
Area() 
} 

class SpatialShape extends Shape 
{ 
-volume 
Volume() 
} 

class Circle extends PlanarShape 
{ 
ShapeClicked() 
} 

class Rectangle extends PlanarShape 
{ 
ShapeClicked() 
} 

class Cube extends SpatialShape 
{ 
ShapeClicked() 
} 

然後修改該函數爲:

public void ShapeClicked(Shape obj) 
{ 
    obj.ShapeClicked(); 
} 

通過多態性,您的調用將被引導到正確的類。

+0

-1否它會違反「是-A」關係。界面(組合)是優選的。 – jgauffin 2012-01-06 12:36:15

+0

@jgauffin它是如何影響is-a關係的? – 2012-01-06 12:40:38

+0

@LuchianGrigore Atul正在C#工作。你已經給了java代碼:) – 2012-01-06 12:43:42

0

使用基本類型是不錯的,當你有你想要繼承共同的行爲。在你的情況下,你真的有一種常見的方式來與你的類型進行交互,但這些類型的行爲是完全不同的。

在這種情況下,你真正要做的是定義一個通用接口,以便類似地處理你的類型。

我將定義如下:

public interface IShape 
{ 
    string Title { get; } 

    string Color { get; } 
} 

public interface I2DShape : IShape 
{ 
    int GetArea(); 
} 

public interface I3DShape : IShape 
{ 
    int GetVolume(); 
} 

然後,可以按CircleRectangleI3DShape實施I2DShapeCube。你的方法則可以實現爲這樣:

public void ShapeClicked(IShape shape) 
{ 
    var shape2d = shape as I2DShape; 

    if(shape2d != null) 
    { 
     shape2d.GetArea(); 
     return; 
    } 

    var shape3d = shape as I3DShape; 

    if(shape3d != null) 
    { 
     shape3d.GetVolume(); 
    } 
} 

你仍然需要檢查的形狀是2D還是3D,但是這只是因爲我們定義的面積和體積作爲單獨的東西。如果你想將它們定義爲單一事物,你可以將它放在基礎接口上,並讓所有類型實現該接口。

+2

基於類型編寫條件代碼的問題是可擴展性。如果以後我們需要另一種形狀,我們有很多工作要做。 – 2012-01-06 12:56:22

+0

這取決於您在面積和體積中添加的其他方法。一維(長度),二維(面積)和三維(體積)似乎涵蓋了所有已知的圖表暗示:)我喜歡這個建議,如果它適合你所面臨的更廣泛的問題,但是你不得不舉出更多的例子。 – tcarvin 2012-01-06 13:51:28

+0

如前所述,如果您考慮面積和體積不同的事情(如理智的人),則只需進行類型檢查。如果你想把它們當作相同的信息,你可以創建一個'GetAreaOrVolume'方法來表示基於'IShape'接口的兩個東西。 – 2012-01-06 16:25:14