1

In my application I fetch files from the user and process it.

Im to limit to a certain scope of file types and each one of these has a different processing approach.

How can I design the application in order that when a new type of file is added, I have to change few to no lines in the controller classes.

Should I be using an Adapter? Wouldn't that be just delegating change responsabilities to another class?

Should I make a representative class for files and deal with them that way?

If possible, provide a (generic) implementation example. It might help to know that Im designing a Spring MVC application and loading files with multipart files. Also, Im checking file type through extension name in the loading file controller [this might have to change].

2
  • 1
    What you want is to have a generic interface with a method providing abstraction (could be anything, maybe even process) and havr concrete implementations of this interface for each file type. You will then have a factory method returning you a concrete instance of said generic interface based on the type of the file you are trying to open.
    – Andy
    Oct 20, 2016 at 10:48
  • Generic interface is in. On the rest let me see if I understood: I create a factory that takes the input and produce an object of the correct type? Oct 20, 2016 at 11:25

1 Answer 1

2

Decorators would fit, one implementation for each of the types, one more as a facade (or dispatcher ? not sure about the term here) routing to the proper implementation.

The facade and the multiple decorator should implements the same interface, here is an example :

public interface FileProces{
    public void process(File file);
    public boolean canProcess(File file);
}

Each decorator should handle his own type of file :

public class JpgFileProces implements FileProces{
    public void process(File file){
        if(!canProcess(file)){
            throw new IllegalArgumentException();
        }
        ...
    }

    public boolean canProcess(File f){
        return f.getContentType.equals("image/jpeg");
    }
}

Then the Facade :

public FacadeFileProces{
    public Set<FileProcess> setProcess;
    public void process(File file){
         for(FileProcess process : setProcess){ 
               if(process.canProcess(file)){
                     process.process(file);
                     break;// you can either do that of for more security, either ensure that you have only one processor and not multiple that are registered.
               }
         }
    }

    public boolean canProcess(File file){
       for(FileProcess process : setProcess){
           if(process.canProcess(file)){
               return true;
           }
       }
       return false;
    }
}

Note : DavidPacker in his comment talked about factory : his solution is more usefull is your FileProcessor are not stateless. If they're not, using a factory returning only singletons is the same that I did, I'm just masking the fact that I have sublayers.

7
  • But then I'll still have to "swich/else if" somewhere to get the correct classes... No? That's where I'm finding trouble, for it will demand some length of maintenance. Oct 20, 2016 at 11:39
  • @TiagoSirious the "if" is in the for loop in the sample i gave. There is only one if in the for loop. The only thing i didn't show you here is how to register you JpgFileProcess in the FacadeFileProcess because i don't know if you use tools like dependency injection (which help a lot), otherwise you can just make JpgFileProcess's constructor take the FacaceFileProcess as a parameter and let him self registering in).
    – Walfrat
    Oct 20, 2016 at 11:43
  • So I made a FIle factory that does this: String type = file.getContentType().toString().toLowerCase(); IProcessableFile processableFile; switch (type) { case "text/plain": processableFile = new FileTxt(file.getName()); default: processableFile = null; } Oct 20, 2016 at 12:53
  • @TiagoSirious you can do it like this, I just did it differently, mine is a bit more flexible, but that flexibility may not be necessary to you. I edited it a bit so you can see the whole picture.
    – Walfrat
    Oct 20, 2016 at 13:53
  • Ok, now I see it! I was missing the canProcess part! Oct 20, 2016 at 17:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.