A Tham wrote:Is my design correct? Please enlighten. Thanks.
It seems that you're slowly getting there by introducing a factory of some sort. Just looking at the code, however, I think it's still too tightly coupled and that several dependencies between concerns could be loosened up.
I'm partial to Alistair Cockburn's hexagonal architecture style so if I were given this code to maintain, I'd probably refactor towards that.
In a hexagonal architecture, any infrastructure concerns like saving or transferring a file is kept decoupled from core business logic like processing a proof, whatever that is in your application. So the ProofProcessingService would be a core-based object/class whereas the SftpTransfer and MinIOTransfer classes would be implementations of an infrastructure-related interface, much like what Stephan is headed toward.
There would be a high reliance on dependency injection in a design that follows the hexagonal architecture. So the ProofProcessingService would be simply be injected with an implementation of the FileTransferService.
Something that stands out as peculiar in your design is the fact that the storeProofs() method takes a FileData parameter and returns the same object. The semantics of that design seems strange to me and makes me question why that's being done.
Ideally, I might expect to see this kind of code:
This isn't as detailed or specific as what Stephan provided but it shows the separation of concerns that I would strive for. The issue I have with your current design is that saveProofs() knows too much about the details of locating a file and transferring a file. I feel that some of that intimate knowledge should be moved to a more appropriate class whose responsibility it is to know that kind of detail.