2015-05-27 63 views
0

我正在創建一個非常基本的Cache對象。這裏是我的代碼:Java OOP多態設計/問題

Cache.java是一個抽象類,旨在被覆蓋。

public abstract class Cache { 

    protected Date dateCreated; 
    protected long expiration; 
    private BuildStrategy strategy; 

    protected Cache(long expiration, BuildStrategy strategy) { 
     this.dateCreated = new Date(); 
     this.expiration = expiration; 
     this.strategy = strategy; 
     strategy.buildAndUpdate(); 
    } 

    private final boolean isExpired() { 
     long duration = new Date().getTime() - this.dateCreated.getTime(); 

     if (duration > expiration) { 
      return true; 
     } 
     return false; 
    } 

    protected void build() { 
     if (!isExpired()) 
      return; 
     setDateCreated(new Date()); 
     buildAndUpdate(); 
    } 

    protected abstract void buildAndUpdate(); 

    final Date getDateCreated() { 
     return dateCreated; 
    } 

    final void setDateCreated(Date dateCreated) { 
     this.dateCreated = dateCreated; 
    } 

    final long getExpiration() { 
     return expiration; 
    } 

    final void setExpiration(long expiration) { 
     this.expiration = expiration; 
    } 
} 

這是一個覆蓋它的一類樣本,ACache.java

public class ACache extends Cache { 

    protected ACache(long expiration) { 
     super(expiration); 
    } 

    private Object variableToBeUpdated; 

    public Object getVariableToBeUpdated() { 
     return variableToBeUpdated; 
    } 

    public void setVariableToBeUpdated(Object variableToBeUpdated) { 
     this.variableToBeUpdated = variableToBeUpdated; 
    } 

    @Override 
    protected void buildAndUpdate() { 
     // ...connects to the database etc... 
     // ...once database stuff is done, update variableToBeUpdated 
     // NOTE: Other caches may implement buildAndUpdate() differently, that's 
     // why it's abstract 
    } 
} 

我在這裏的問題是,我想隱藏buildAndUpdate()方法,只是暴露的Cachebuild()方法,因爲爲了爲了更新Cache,我想檢查它是否先到期。

由於buildAndUpdate()protected,該方法可以由類本身訪問。我如何繼續我想要做的事情?你如何改進我的實施?

編輯1:採取ControlAltDel和Turing85的建議,並與IoC一起去。我創建了一個名爲BuildStrategy的接口,它有一個void buildAndUpdate()方法。它是否正確?

+2

'Cache'類中的'buildAndUpdate'是抽象的,所以不能從'ACache'中調用,如果這是你所擔心的。 – GriffeyDog

+0

什麼?它完全可以在'ACache'中調用。 'ACache'覆蓋'buildAndUpdate()'方法,並且因爲它是'Cache'中的'protected abstract',這意味着它在'ACache'中被覆蓋時將具有'protected'修飾符。這就是問題所在。 – mpmp

+0

暴露給誰? – biziclop

回答

2

你可以去的一種方法是完全擺脫這種方法,而是在BuildAndUpdate類中創建,這將是構造函數中的必需參數。然後,您可以繼承您的Cache類,並在一個空構造函數中使用BuildAndUpdate對象初始化超類。

有意義嗎?

+0

你的意思是[控制反轉](http://en.wikipedia.org/wiki/Inversion_of_control)? – Turing85

+0

嗯......我迷失在'......這將是構造函數中必需的參數。「我不明白你的意思。 – mpmp

+0

@MiguelPortugal看看我的鏈接。基本上,您需要構建一個管理對象,管理一個特定「Cache」的'buildAndUpdate'進程並將該管理對象傳遞到'Cache'類(應將其存儲爲屬性以供將來使用)。 – Turing85

1

您可以使用泛型。不知道爲什麼你需要課堂抽象。需要特殊行爲的人,他們可以擴大你的班級。

import java.util.Date; 
import java.util.Map; 

public class Cache<K,V> { 
private Map<K,V> map; 
protected Date dateCreated; 
protected long expiration; 

protected Cache(long expiration) { 
    this.dateCreated = new Date(); 
    this.expiration = expiration; 
    buildAndUpdate(); 
} 

private final boolean isExpired(){ 
    long duration = new Date().getTime() - this.dateCreated.getTime(); 

    if (duration > expiration){ 
     return true; 
    } 
    return false; 
} 

protected void build(){ 
    if (!isExpired()) return; 
    setDateCreated(new Date()); 
    buildAndUpdate(); 
} 

protected void buildAndUpdate(){ 
    //populate map here 
} 

final Date getDateCreated() { 
    return dateCreated; 
} 

final void setDateCreated(Date dateCreated) { 
    this.dateCreated = dateCreated; 
} 

final long getExpiration() { 
    return expiration; 
} 

final void setExpiration(long expiration) { 
    this.expiration = expiration; 
} 
0

我最終什麼事做的是我感動的是管理的所有在另一個包中的Cache對象的類。我喜歡控制反轉的想法,使代碼看起來更加平滑和模塊化 - 這就是爲什麼我將它標記爲最佳答案的原因。