I am creating a very basic Cache
object. Here is my code:
Cache.java
is an abstract class meant to be overriden.
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;
}
}
This is a sample of a class that overrides it, 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
}
}
My problem here is that I want to hide the buildAndUpdate()
method and just expose the build()
method of Cache
because in order for the Cache
to be updated, I would want to check if it's expired first.
Since buildAndUpdate()
is protected
, the method can be accessed by the class itself. How do I proceed with what I want to do? How can you improve my implementation?
EDIT 1: Took ControlAltDel and Turing85's advice and went with IoC. I created an interface called BuildStrategy
that has a void buildAndUpdate()
method. Is this correct?
One way you could go would be to get rid of this method entirely, and instead create at BuildAndUpdate class, which would be a required parameter in the constructor. You could then subclass your Cache class, and in an empty constructor, initialize the superclass with a BuildAndUpdate object.
Make sense?
you can use generics. Not sure why you need class to be abstract. People who require special behaviour, they can extend your 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;
}
What I ended up doing is I moved the class that managed all the Cache
objects in another package. I liked the idea of Inversion of Control though, makes the code looks smoother and modular - which is why I marked it as the best answer.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.