2010-04-30 95 views
4

目前,我有這樣的代碼(我不喜歡它):如何將默認值設置爲方法的所有錯誤或空參數?

private RenderedImage getChartImage (GanttChartModel model, String title, 
            Integer width, Integer height, 
            String xAxisLabel, String yAxisLabel, 
            Boolean showLegend) { 
    if (title == null) { 
     title = ""; 
    } 
    if (xAxisLabel == null) { 
     xAxisLabel = ""; 
    } 
    if (yAxisLabel == null) { 
     yAxisLabel = ""; 
    } 
    if (showLegend == null) { 
     showLegend = true; 
    } 
    if (width == null) { 
     width = DEFAULT_WIDTH; 
    } 
    if (height == null) { 
     height = DEFAULT_HEIGHT; 
    } 
    ... 
} 

我怎麼能提高呢?

我有一些關於引入一個將包含所有這些參數作爲字段的對象的想法,然後,也許可以應用生成器模式。但是仍然沒有清晰的眼光來實現這一點,我不確定這是值得做的。任何其他想法?

回答

3

所以很多參數一種方法絕對是一種代碼味道。我會說Chart對象正在等待誕生。這是一個基本的輪廓:

private RenderImage getChartImage(Chart chart) { 
    //etc. 
} 
private static class Chart { 
     private GanttChartModel model; 
     private String title = ""; 
     //etc, initializing each field with its default value. 
     private static class Builder { 
      private Chart chart; 
      public Builder(GanttChartModel model) { 
       chart = new Chart(); 
       chart.model = model; 
      } 
      public setTitle(String title) { 
       if (title != null) { 
        chart.title = title; 
       } 
      } 
     } 
    } 

其他選項包括使用的方法,而不是對象,表明空原語是不允許的,雖然這並不一定做的更好。另一個選擇是一堆重載方法,但是在給定參數類型的情況下,這並不實際,因爲我認爲你想讓任何參數成爲可選參數,而不是第一個參數是必需的,而後面的參數是可選的。

1

您的方法的目的是構造一個複雜的對象。因此,生成器模式似乎適用於解決此問題。構建器可以管理許多用於創建對象的選項。

圖像的某些屬性不應該有默認值。例如,沒有標題的圖像不是很有用,但這取決於您的應用程序的需求。

使用的助洗劑可以是這樣的:

RenderedImage image = RenderedImageBuilder.getNew(model) 
         .title("title").width(100).height(100) 
         .showLegend().build(); 

建設者的另一個優點是,他們可以很容易地記錄了參數的任何違約,它們應該如何使用。

0

那麼,我在想有沒有一些框架支持@NotNull註釋,如果一個方法有這個註釋,框架將檢查所有的參數。

@NotNull public void doSomething(Parameter a, Parameter b) { }

1

我能想到的手,最好是引進Parameter Object(這也將是一個建設者)呼籲像ChartOptions包含此方法的所有選項。

對象可堆壘起來:

ChartOptions options = new ChartOptions() 
    .setHeight(10) 
    .setWidth(100) 

getChartImage(model, options); 

如果不工作,你至少可以封裝空校驗:

private <A> A checkNull(A object, A default) 
{ 
    return object == null ? default : object; 
} 
1

我會將該邏輯移動到您要返回對象的類的setter方法中。

public class MyRenderedImage implements RenderedImage { 

    public MyRenderedImage(String title, ...) { 
     // constructor should call setters that do validation/coercion 
    } 

    public void setTitle(String title) { 
     if (title == null) { 
      this.title = ""; 
     } 
    } 

    ... 
} 

另一種選擇要考慮的是拋出一個InvalidArgumentException,但它聽起來像是你已經知道你想要做什麼。

0

您可以擁有最初構建的地圖值。你可以這樣做,

private RenderedImage getChartImage(GanttChartModel model, String title, 
     Integer width, Integer height, String xAxisLabel, 
     String yAxisLabel, Boolean showLegend) { 

    title = removeNull(KEY_TITLE,title); 
    xAxisLabel = removeNull(KEY_X,xAxisLabel); 
    yAxisLabel = removeNull(KEY_Y,yAxisLabel); 
    showLegend = removeNull(KEY_LEG,showLegend); 
    width = removeNull(KEY_W,width); 
    height = removeNull(KEY_H,height); 
} 

//initialize the defaultMap with the key-value of default pairs 
Map<Object,Object> defaultMap; 

private Object removeNull(Object keyTitle, Object value) { 
    if(value==null){ 
     return defaultMap.get(keyTitle); 
    } 
    return value; 
} 
相關問題