2014-04-11 73 views
0

我正在建立一個座標/向量的數學庫。Java OOP層次結構 - 避免開銷

有一個ReadableCoordWritableCoord interfraces。

AbstractCoordValue可以擴展以覆蓋座標獲取器。

的問題是,在不可變的座標的方法(AbstractCoordValue)可以實現兩種方式,如在此被視爲VARIANT 1VARIANT 2

我的DRY膽量告訴我去第一個(然後impl是在一個地方只),但我不知道如果第二個沒有較少的開銷

要使用哪一個?

public abstract class AbstractCoordValue implements ReadableCoord { 

    // x(), y(), z() are abstract getters from the interface 

    @Override 
    public WritableCoord copy() 
    { 
     return new CoordVariable(x(), y(), z()); 
    } 

    /* VARIANT 1 */ 
    @Override 
    public WritableCoord add(double x, double y, double z) 
    { 
     return copy().add_ip(x(), y(), z())); 
    } 

    /* VARIANT 2 */ 
    @Override 
    public WritableCoord add(double x, double y, double z) 
    { 
     return new CoordVariable(x()+x, y()+y, z()+z)); 
    } 

    // --- snip --- 
} 

和延伸類,可變:

public class CoordVariable extends AbstractCoordValue implements WritableCoord { 

    private double x, y, z; 

    // implements x(), y(), z() as getters 

    public CoordVar(double x, double y, double x) { 
     this.x = x; 
     this.y = y; 
     this.z = z; 
    } 

    @Override // "_ip" stands for "in place" 
    public WritableCoord add_ip(double x, double y, double z) 
    { 
     this.x += x; 
     this.y += y; 
     this.z += z; 

     return this; 
    } 

    // --- snip --- 
} 

回答

0

我建議實施與實現Readable接口,並帶有可變座標另一類同時實現了ReadableWritable接口不變的座標最後一類 - 即避免使用繼承,因爲使用mutable擴展不可變實現違反了LSP(Liskov替換)原則,並且包含了像處理不可變類一樣處理可變類的潛在漏洞。

+0

好的一點,但我希望可變的人也有所有的「做一個副本」的方法。或者這是一個壞主意? – MightyPork

+0

不是真的,考慮以輕微的其他方式實現'add' - 例如,用sum創建不可變的coords,不創建coords,然後添加一些東西 - 即變體2.我也應該讓你知道,我總是喜歡並推薦使用不可變類/變量,因爲它們在大多數情況下都是線程安全的。 –

+0

其實你對我的幫助非常大,現在所有的工作都非常容易。此外,鏈接呼叫時不會再有臨時Coords污染內存。其實並不嚴格按照你的意見,因爲即。 'MutableCoord'上的add()會返回自己,而'ImmutableCoord'上的add()返回一個新的'MutableCoord'結果。因此,在鏈接呼叫時,它會自動切換到可變狀態以節省內存。 (而且它是泛型,所以全部都在javadoc中......我覺得很酷,也許不是100%的LSP,但對我有用。 – MightyPork