2011-07-16 48 views
3

我常常陷入的情況時,我想使用模板方法模式,但模板方法需要不同類型的參數,如:模板方法模式

public abstract class AbstractFoo { 

    public void process(TypeA a, TypeB b) { 

    //do common processing 
     if (b == null) { 
      doProcess(a); 
     } else if(a == null) { 
      doProcess(b); 
     } 
    } 

    public abstract void doProcess(TypeA a); 
    public abstract void doProcess(TypeB b); 
} 

這看起來不太好。提供的參數之一必須爲空,並且所有服務都必須爲其他類型實施虛擬doProcess方法。有沒有更好的模式呢?你如何處理這個問題?我不想使用構造函數,因爲這些服務是spring bean。同樣的問題也適用於策略模式。

+0

怎麼樣使用泛型? –

回答

3
public abstract class AbstractFoo<T> { 

    public void process(T a) { 

     //do common processing 

     doProcess(a); 
    } 

    protected abstract void doProcess(T a); 
} 

public class Person extends AbstractFoo<Person> { 
    @Override 
    protected void doProcess(Person p) { 
     p.draw(); 
    } 
} 


public class Car extends AbstractFoo<Car> { 
    @Override 
    protected void doProcess(Car c) { 
     c.draw(); 
    } 
} 
+0

現在的問題是,他將不得不爲TypeA和TypeB創建單獨的類。我刪除了我以前的評論,以防止混淆。 –

+0

我沒有看到創建兩個單獨的類的問題。對於每種類型和在實現的'doProcess(T)'方法中的某些特定操作,必須執行一個通用計算。 –

+0

我現在實際上同意你的意見。但我建議你也在你的答案中顯示子類的例子。這將使其清晰。 –

2

你說得對,它絕對不是模板方法模式,但我不確定你想要做什麼。也許你是在工廠模式之後:

interface Foo { 
    boolean isA(); 
    boolean isB(); 
    ... 
} 

class ProcessorFactory { 
    public Processor getProcessor(Foo foo) { 
     if (foo.isA()) { 
      return new AProcessor(); 
     } 
     if (foo.isB()) { 
      return new BProcessor(); 
     } 
     ... 
    } 
} 

至於構造函數,我所有的spring bean都有構造函數來表示它們的依賴關係。那有什麼問題?

+0

這個例子表達了我想要做的。處理甚至不能共享接口的類型。我的意思是我不能使用構造函數來提供參數。這將是醜陋的... – lisak

2

我覺得使用Wrapper類可以解決這個問題。包裝類可以是一個簡單的Holder實體。你甚至可以考慮封裝你的應用程序特定的屬性包裝類(更多的上下文線)。使用這種方法,您只需要一個處理方法,並且只有具有正確類型的子類纔會處理消息。爲了避免代碼重複,你也可以在抽象類中進行檢查。看下面的例子,

public class Context { 
private Object body; 
public Context(Object obj) { 
    body = obj; 
} 
public Object getBody() { 
    return body; 
} 
} 

public abstract class AbstractFoo { 

public void process(Context ctx) { 
//do common processing 
    if (canProcess(ctx)) { 
     doProcess(ctx.getBody()); 
    } 
} 

protected abstract <T extends Object> boolean canProcess(T obj); 
protected abstract <T extends Object> void doProcess(T obj); 
} 
+0

顯然你可以用你的項目特定的接口替換對象。 –