I have a class that i use to do downloads. The class is observable and i use it as a swing UI model object too. However it is too slow, both to start (from the http handshaking i presume so not much i can do about it probably) and from synchronized access. The interface of the class is:
public File getDownloadedFile()
public String getMimeType()
public synchronized BigInteger getExpectedSize()
public URL getURL()
public synchronized boolean cancel()
public synchronized boolean retry()
public synchronized boolean isDone()
public synchronized boolean isCancelled()
public synchronized BigInteger getProgress()
public String getName()
public synchronized BigInteger getBytesRead()
public synchronized BigDecimal getBytesPerSecond()
public synchronized BigDecimal getTimeRemaining()
public synchronized void start()
I want to eliminate the synchronized(s) there, but i know that to do so, i have to make a way to turn this class immutable. I tried to model this as a state machine (hidden internally), however the middle (running) state has a InputStream + a thread. What is the correct way to turn this into a immutable wrapper? 1) Make class into a wrapper for a state machine + the immutable state. Make start start the first machine state, then notify observers on each state change with a immutable copy. (however the client expectation of a monolitic class - for the model of the swing ui for ex, is problematic.
2) Give up on using the wrapper as swing model. just register my controller as a observer, start and add the first (immutable) state as a model and use a immutable state identifier (for example the download url) to recognize the download state machine state emitted by notifyObservers() as belonging to some download, to replace each successive state + update the ui. However i don't think this is very usable when this is used without interest in notification. At least a way to wait for the download to be complete would be nice no?