2013-07-10 62 views
0

A Request類有一個屬性colorType它可以是不同的顏色。根據顏色的類型,它會涉及到不同的處理方式。如何更好地設計此代碼和邏輯

這裏是控制器代碼:

def colorInstance = Color(params) 
//validates and checks the params. Also, based on some logic sets the `colorType` property 
//to be appropriate color 
if (colorInstnace.validate()) 
{ 
    colorService.processColor(colorInstance) 
} 

這裏是colorService代碼:

void processColor(Color colorInstance) { 
    if (colorInstance.colorType == "green") 
     processGreen(colorInstance) 
    else if (colorInstance.colorType == "red") 
     processRed(colorInstance) 
    .... 
    ...... 
} 

processGreen(Color colorInstance) { 
    //common code 
    //code specific to colortypes that are GREEN 
    //more common code 
} 

processRed(Color colorInstance) { 
    //common code 
    //code specific to colortypes that are RED 
    //more common code 
} 

問題

  1. 我如何更改代碼的服務,使我不必複製粘貼所有processXXX中的代碼方法?
  2. 如何消除processColor方法中的if/elseif

回答

1

服務類可以有以下實現。 groovy中的Switch case可以處理任何值,你不需要使用任何原始數據類型。

void processColor(Color colorInstance) { 
    processCommonCodeBefore(colorInstance) 
    processColorSpecificCode(colorInstance) 
    processCommonCodeAfter(colorInstance)  
} 

processCommonCodeBefore(Color colorInstance) { 
    //common code 
} 

processCommonCodeAfter(Color colorInstance) { 
    //common code 
} 

processColorSpecificCode(Color colorInstance) { 
    switch(colorInstance.colorType){ 
     case 'green': 
      processGreen(colorInstance) 
      break 
     case 'blue': 
      processBlue(colorInstance) 
      break 
     default: 
      processDefault(colorInstance) 
    }  
} 

這樣,服務類中的所有方法都可以高效地進行單元測試。

1

我認爲如果您使用整型常量來代替它會更容易。

// you could use actual RGB too.. then red would be 0xff0000 
static final int RED = 0 
static final int BLUE = 1 
static final int GREEN = 2 

然後在colorService,你可以嘗試這樣的事情......

void processColor(Color colorInstance) { 
    commonMethodOne(); 

    switch(colorInstance.colorType){ 

    case RED: 
    //Handle the red color 
    case BLUE: 
    // Handle the blue color, etc. 

    } 

    commonMethodTwo(); 
} 

commonMethodOne(){ 
    //Here is code that gets executed regardless of Color 
} 

commonMethodTwo(){ 
    //Here is more code that gets executed regardless of Color 
} 
+0

如果他使用Groovy,他應該繼續使用類型安全的枚舉,而不是整型常量。 – chrylis

1

即使答案已被接受,我想指出一個替代解決方案,使用enum代替ColorType

class Color { 
    ColorType colorType 
    ... 
} 

enum ColorType { 
    blue { 
     @Override void process(Color color) { 
      // code for processing blue 
     } 
    }, 
    green { 
     @Override void process(Color color) { 
      // code for processing green 
     } 
    }, 
    red, 
    yellow 

    void process(Color color) { 
     // used for red and yellow 
    } 
} 

像Java中你可以添加方法,以枚舉(如process(Color color))。您也可以針對某些枚舉常量重寫這些方法。在此示例中,枚舉值blue和​​將覆蓋process(Color color)方法。

使用這種方法,你就可以做到這一點:

void processColor(Color colorInstance) { 
    commonMethod(colorInstance) 
    colorInstance.colorType.process(colorInstance) 
    otherCommonMethod(colorInstance) 
} 

這個例子的問題是,它創造ColorColorType應避免其之間的循環依賴。但根據您的實施情況,可能會從ColorType.process()方法中刪除color參數來解決此問題。

我只是想指出的是,重寫枚舉的方法有時是針對這種情況,一個非常有用的功能:-)

+0

'Color'是一個由OP的問題中的grails域類表示的持久實體,它應該將實體作爲類的成員。因此,'colorType'將代表'COLOR'表中的'COLOR_TYPE'列,儘管你的方法對於POGO類可能很方便。 – dmahapatro

+0

嗯,我不明白你的意思。您可以在域類中引用/保存枚舉而不會出現問題。 – micha