2016-11-11 128 views
1

我正在尋找的改進方案,以下列問題的instanceof避免。我有一個東西傳給工廠,工廠將檢查對象類型,創建另一個類型,用來自傳入對象的數據填充它,並返回新類型。在工廠方法

... 

public MyAbstractClass create(MyObject a) { 

    if (a instanceof A) { 
     A obj = (A) a; 
     return new MyAbstractClass_1 (obj.getField(), factoryField); 
    } 
    else if (a instanceof B) { 
     B obj = (B) a; 
     return new MyAbstractClass_2 (obj.getSomething(), obj.getSomethingElse(), factoryField); 
    } 

} 

返回類型的實例被統稱爲後綴。展望未來,我需要支持更多類型的,如果可能,我想避免的instanceof解決方案。我該如何改進?

回答

2

您可以添加創建方法MYOBJECT呢?這樣你就不再需要實例了,因爲MyObject的每個實例都知道如何「創建」。你不會有一個工廠了,雖然:(

它會看起來像(假設爲MyObject是一個接口,如果它是一個類,那麼就不是延長。):

interface MyObject { 
    ... 
    public MyAbstractClass create(MyObject a); 
    ... 
} 

public class A implements MyObject { 
    ... 
    public MyAbstractClass create(MyObject a) { 
    return new MyAbstractClass_1 (obj.getField(), factoryField); 
    } 
    ... 
} 

public class B implements MyObject { 
    ... 
    public MyAbstractClass create(MyObject a) { 
    return new MyAbstractClass_2 (
     obj.getSomething(), 
     obj.getSomethingElse(), 
     factoryField); 
    } 
    ... 
} 
0

if的屍體聲明應該是MyObject虛擬或抽象成員。

abstract class MyObject { 
    public abstract MyAbstractClass create(); 
} 

class A extends MyObject { 
    @Override 
    public MyAbstractClass create(Object factoryField) { 
     return new MyAbstractClass_1 (this.getField(), factoryField); 
    } 
} 

class B extends MyObject { 
    @Override 
    public MyAbstractClass create(Object factoryField) { 
     return new MyAbstractClass_2 (this.getSomething(), this.getSomethingElse(), factoryField); 
    } 
} 

一般來說,當你看到自己的檢查對象的類型取決於具體類型做不同的事情,則可能意味着你應該全光照g多態,代碼應該自己進入具體的類型。

更新的MyObject數據應該從目前的情況是未來,而不是作爲一個參數傳遞,正如你所指出。唯一的問題是,我不知道你現在將factoryField放在哪裏。你可以如上將它作爲一個參數,因爲這些都是虛擬的成員你仍然可以有一個工廠,以及:

class SomeFactory { 
    private Object factoryField; 

    public SomeFactory(Object factoryField) { 
     this.factoryField = factoryField; 
    } 

    public MyAbstractClass create(MyObject a) { 
     return a.create(factoryField); 
    } 
} 
+0

什麼的'create'方法採取任何參數的原因是什麼?該實現具有創建該對象所需的內容 - 「factoryField」除外。 – user1491636

+0

@ user1491636你說得對,這些信息應該從實例來現在 –

+0

你更新的解決方案是一個我在想......不知道這是否真的是一個工廠了,雖然:) – user1491636