I have a business case in which 3 things need to happen, in sequence:
Now, the Abstract Class FileTransfer provides implementation for 1. downloadFiles() and 3. upload(), but not 2. process() -- child classes (like MusicFileTransfer or VideoFileTransfer or PDFFileTransfer) will do different things in the 2. process() stage.
So it seems clear to make the abstract class like so:
public abstract class FileTransfer {
public void download() {
// implementation provided
}
public abstract void process(); // implementation not provided
public void upload() {
// implementation provided
}
}
But one issue -- There will never ever be a time in which it is okay for, say, MusicFileTransfer to call process() before download() or any other order. The process must always be 1. download(), 2. process(), then 3. upload().
So I imagine something like:
public void doTransfer() {
// private methods since we want to enforce this order of execution
download(); // implem provided
process(); // abstract method
upload(); // implem provided
}
in FileTransfer to wrap around these three calls. But in order for the child class MusicFileTransfer to override process() ... it must be public or protected (not private).
What should I do to work around this pickle? Have a public doTransfer() and a public process() and just make sure process() is never ever called? Or do away with the doTransfer() and hope that the order is always correct?
You need the template method pattern. Create a doTransfer method (final) in the FileTransfer class that defines the order of the methods that needs to be called. Make the download and upload methods also final so they can't be overridden. The process method is the abstract method; make it protected so it can't be called from other classes. It can't be public, or else it can be called by some other class out of order.
public final void doTransfer() {
// protected methods since we want to enforce this order of execution
download(); // implem provided
process(); // abstract method
upload(); // implem provided
}
protected final void download() {
// implementation provided
}
protected abstract void process(); // implementation not provided
protected final void upload() {
// implementation provided
}
Then subclasses can only implement the process method and they can't override any other methods.
In this case you might consider making the process() method protected, meaning that subclasses can extend it, but consumers may not call it directly. Additionally, perhaps download() and upload() methods shouldn't be public either. Consider the the following:
public abstract class FileTransfer {
private void download() {
// implementation provided
}
protected abstract void process(); // implementation not provided
private void upload() {
// implementation provided
}
public void doTransfer() {
// private methods since we want to enforce this order of execution
download(); // implem provided
process(); // abstract method
upload(); // implem provided
}
}
Sample implementation class:
public class FTPFileTransfer {
protected void process() {
// implement FTP file transfer here
}
}
Sample consumer method:
public void consumerMethod() {
FileTransfer fileTransfer = factory.getFTPFileTransfer();
fileTransfer.doTransfer();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With