17
What is and how the Adapter standard works in Java, I am trying to understand this pattern because I will use it in a project.
17
What is and how the Adapter standard works in Java, I am trying to understand this pattern because I will use it in a project.
17
In summary, the design pattern Adapter consists of adapting the interface of a class or object to be used otherwise, but without changing the interface or implementation.
A common case is when we develop a code client that intends to use several heterogeneous sources.
For example, you have multiple implementations capable of reading and recording files from various services:
class DropBox {
void upload(DropBoxFile dbFile) {}
DropBoxFile download(String id) {}
}
class AWS {
void save(InputStream input, int id) {}
InputStream restore(int id) {}
}
class GoogleDrive {
void send(byte[] data, String name) {}
byte[] get(String name) {}
}
Each of these classes is in a different library or project. You do not want to make changes or duplicate the code.
Now imagine that you have a system where the user can decide on which service the data will be saved. One way out is to write a procedural code full of if
s and else
s each time the system needs to use one of the available services, example:
if (dropbox) {
//faz alguma coisa
} else if (aws) {
//faz outra
} else if (drive) {
// outra ainda
}
But you will not want this several times on the system, plus the code needed to convert the system types to the specific types of services. Think about how much maintenance it would take to add a new service
Then we can define a persistence interface:
interface Persistencia {
void gravar(File file);
File ler(String id);
}
The whole system would be implemented using only this interface. A wonder from the point of view of Object Orientation, without if
s, no need to change the code if any service changes.
But the problem is not completely solved. Service classes that we don’t want to change don’t implement our interface.
So for each service, we should implement an adapter. For example:
class DropBoxAdapter implements Persistencia {
DropBox dropBox;
DropBoxAdapter(DropBox dropBox) {
this.dropBox = dropBox;
}
void gravar(File file) {
dropBox.upload(new DropBoxFile(file.getAbsolutePath());
}
File ler(String id) {
DropBoxFile dbFile = dropBox.download(id);
return new File(dbFile.getLocalPath());
}
}
Note that we have just created a class that allows us to use an object DropBox
using the interface Persistencia
. Us we adapt the original class according to the desired interface.
Other implementations of Adapters should then be provided for other services using the same principle.
Now imagine that we have to maintain a poorly designed system that implements logs manually using the following class:
class HomeMadeLog {
public void log(int nivel, String mensagem, Throwable erro) {
String s = formatarLog(nivel, mensagem, erro);
adicionaLogNoArquivo(s);
}
private String formatarLog(...) { }
private String adicionaLogNoArquivo(...) { }
}
We need to modernize logs using a framework like Log4j, but there are thousands of calls to the old method and many of them are too complicated to simply do an automatic overwrite.
What’s more, we want to avoid generating 99% change of the project files, as this would generate a major conflict problem in the version control system for all other developers.
One solution is to extend the class HomeMadeLog
so that it is an adapter for Log4j. Example:
class HomeMadeLogToLog4jAdaptor extends HomeMadeLog {
Logger logger = Logger.getLogger();
@Override
public void log(int nivel, String mensagem, Throwable erro) {
if (nivel == 0) logger.debug(mensagem, erro);
else if (nivel == 1) logger.info(mensagem, erro);
else if (nivel == 2) logger.error(mensagem, erro);
}
}
Now just provide an instance of HomeMadeLogToLog4jAdaptor
instead HomeMadeLog
and all classes will work with Log4j without modifications.
Note that the main trump of the project pattern Adapter is to allow reuse of code consistently while maintaining compatibility with other libraries and earlier versions of code.
A class adaptor is nothing more than a class that implements the interface you want to use and delegates the actual execution to a third class that has the implementation we want to use.
Note also that my examples are purposefully simplified. Some details and complexities that are unrelated to the pattern itself have been omitted to avoid complicating the examples.
In the case of the Log4j example, I would necessarily have to replace the Homemadelog class reference with Homemadelogtolog4jadaptor in all classes, correct? Or in this example you are considering that who provides the Homemadelog would be a static constructor and in this case just replace the return by the subclass?
Browser other questions tagged java pattern-design adapter
You are not signed in. Login or sign up in order to post.
It’s weird that you want to wear something you don’t understand. Patterns aren’t meant for you to choose and use. They were made to use when there is a need. And to know if you have the need you need to understand it.
– Maniero
Perhaps the standard is quoted in the architecture document, it is common when a system or part of it is designed at a high level and the implementation is delegated to another team.
– utluiz
It’s college project, teacher’s requirement @bigown
– Tiago Ferezin
Making a basic cramp in Stackoverlow. Kidding :)
– Wallace Maxters
@Wallacemaxters is more or less, more to understand msm, because I have to develop a project in this pattern
– Tiago Ferezin