Java OOP 多态性 design/issue
Java OOP polymorphism design/issue
我正在创建一个非常基本的 Cache
对象。这是我的代码:
Cache.java
是一个抽象 class 意味着被覆盖。
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;
}
}
这是覆盖它的 class 的示例,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()
方法,只公开 Cache
的 build()
方法,因为为了更新 Cache
,我想先检查它是否过期。
由于 buildAndUpdate()
是 protected
,因此 class 本身可以访问该方法。我该如何继续我想做的事情?您如何改进我的实施?
编辑 1:采纳了 ControlAltDel 和 Turing85 的建议并采用了 IoC。我创建了一个名为 BuildStrategy
的接口,它有一个 void buildAndUpdate()
方法。这是正确的吗?
您可以采取的一种方法是完全摆脱此方法,而是在 BuildAndUpdate class 处创建,这将是构造函数中的必需参数。然后你可以 subclass 你的 Cache class,并在一个空的构造函数中,用一个 BuildAndUpdate 对象初始化 superclass。
有道理吗?
您可以使用泛型。不确定为什么需要 class 是抽象的。需要特殊行为的人,他们可以扩展您的 class.
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;
}
我最终做的是将管理所有 Cache
对象的 class 移动到另一个包中。不过,我喜欢控制反转的想法,它使代码看起来更流畅和模块化 - 这就是为什么我将其标记为最佳答案的原因。
我正在创建一个非常基本的 Cache
对象。这是我的代码:
Cache.java
是一个抽象 class 意味着被覆盖。
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;
}
}
这是覆盖它的 class 的示例,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()
方法,只公开 Cache
的 build()
方法,因为为了更新 Cache
,我想先检查它是否过期。
由于 buildAndUpdate()
是 protected
,因此 class 本身可以访问该方法。我该如何继续我想做的事情?您如何改进我的实施?
编辑 1:采纳了 ControlAltDel 和 Turing85 的建议并采用了 IoC。我创建了一个名为 BuildStrategy
的接口,它有一个 void buildAndUpdate()
方法。这是正确的吗?
您可以采取的一种方法是完全摆脱此方法,而是在 BuildAndUpdate class 处创建,这将是构造函数中的必需参数。然后你可以 subclass 你的 Cache class,并在一个空的构造函数中,用一个 BuildAndUpdate 对象初始化 superclass。
有道理吗?
您可以使用泛型。不确定为什么需要 class 是抽象的。需要特殊行为的人,他们可以扩展您的 class.
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;
}
我最终做的是将管理所有 Cache
对象的 class 移动到另一个包中。不过,我喜欢控制反转的想法,它使代码看起来更流畅和模块化 - 这就是为什么我将其标记为最佳答案的原因。