简体   繁体   中英

Java OOP polymorphism design/issue

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM