Why #RestControllerAdvice related aop? - aop

During to study aop(Aspect Oriented Programming)
I discoverd wired thing. Many blog explained #RestControllerAdvice used aop but I can't find related to aop annotation in #RestControllerAdvice.
#RestControllerAdvice(basePackageClasses = PostController.class)
public class ApiControllerAdvice {
#ExceptionHandler(MethodArgumentNotValidException.class)
#ResponseStatus(HttpStatus.BAD_REQUEST)
public ResponseEntity<Map<String, String>> handleValidationExceptions(MethodArgumentNotValidException ex){
Map<String, String> errors = new HashMap<>();
errors.put("statusCode", String.valueOf(HttpStatus.BAD_REQUEST));
ex.getBindingResult().getAllErrors()
.forEach(c -> errors.put(((FieldError) c).getField(), c.getDefaultMessage()));
return ResponseEntity.badRequest().body(errors);
}
Why #RestControllerAdvice related aop?

Related

How to Solve Parallel Inheritance Hierarchies when we try to reuse code through inheritance

Recently in a job interview, they ask me "how to solve Parallel Inheritance Hierarchies when we try to reuse code through inheritance". I thought on Aggregation or Composition, but i was a little confused on making an example based on that.
So I decided to leave it pending to deepen concepts later, but after investigating it did not end up forming a precise answer to that question, could someone explain me a solution or an example to this?
Parallel Inheritance Hierarchies makes many unnecessary classes and makes code very fragile and tightly coupled.
For example, we have class Sportsman and its Goal's.
public abstract class Sportsman
{
public string Name { get; set; }
public abstract string ShowGoal();
}
and concrete class Footballer:
public class Footballer : Sportsman
{
public override string ShowGoal()
{
return new FootballerGoal().Get();
}
}
and Runner:
public class Runner : Sportsman
{
public override string ShowGoal()
{
return new RunnerGoal().Get();
}
}
Then we have their goals:
public abstract class Goal
{
public abstract string Get();
}
and its concrete classes:
public class FootballerGoal : Goal
{
public override string Get()
{
return "Score 1 goal";
}
}
And runner goal:
public class RunnerGoal : Goal
{
public override string Get()
{
return "Run 1 km";
}
}
Now, it can be seen that if we add new type of sportsman, then we need add a new class to hierarchy of Goal.
We can try to avoid of creation of that hierarchy tree by using dependency injection and extracting method to interface.
At first, we create interface:
public interface IGoal
{
string Visit(Sportsman sportsman);
}
and then just implement it:
public class FootballerGoal : IGoal
{
public string Visit(Sportsman sportsman)
{
return "Score 1 goal";
}
}
and use it in Footballer class:
public class Footballer : Sportsman
{
public string ShowGoal(IGoal goal)
{
return goal.Visit(this);
}
}
Now we do not have hierarchy tree and we can call it like this:
new Footballer().GetGoal(new FootballerGoal())
UPDATE:
There is a good article about Parallel Inheritance Hierarchies.. It proposes some ways to solve this task. Let me show the third way.
Solution 3 Collapse a hierarchy.
Pros:
Only maintain One hierarchy
Easy to maintain
Cons
Breaks SRP fairly often.
So Footballer class would like this:
public class Footballer : Sportsman
{
public override string ShowGoal()
{
return new FootballerGoal().Get();
}
public string GetGoal()
{
return "Score 1 goal";
}
}
And Runner class would like this:
public class Runner : Sportsman
{
public override string ShowGoal()
{
return new RunnerGoal().Get();
}
public string GetGoal()
{
return "Run 1 km";
}
}
The c2 wiki has a page on parallel inheritance hierarchies where ChaoKuoLin lists four possible solutions. I paraphrase them here, along with some context for each. See the original page for a full explanation including advantages, disadvantages, and examples.
Keep the parallel hierarchies.
When the hierarchies have separate responsibilities and each contains many methods.
When maximum flexibility is required.
Keep one of the hierarchies and collapse the other into a class.
When one of the hierarchies can be reduced to a single class, for example by moving some methods to the other hierarchy.
When one of the hierarchies contains few methods.
Collapse the two hierarchies into one.
When the hierarchies have similar responsibilities and each contains few methods.
Keep a partial parallel hierarchy with the rest collapsed.
When you want a middle ground among the previous solutions.
Another solution suggested in the wiki is Mix In and it is also suggested in How to solve parallel Inheritance in UI case?

Is there an object-oriented alternative to the Front Controller Pattern?

Okay, so i stumbled upon the Front Controller Pattern, and as far as i know from web frameworks like Spring Web (Java) or Flask (Python), they all embody this Design Pattern, leading to code such as (sample Spring Web):
#PreAuthorize("hasAnyAuthority('ROLE_USER','ROLE_ADMIN','ROLE_SYSADMIN')")
#GetMapping(value = "/path/to/{id}/somewhere")
public void doIt(#PathVariable("id") String id)
{
// ...
}
#PostMapping(value = "/path/to/{id}/somewhere")
#PreAuthorize("hasAnyAuthority('ROLE_ADMIN','ROLE_SYSADMIN')")
public SomeDto doSomething(#PathVariable("id") String id)
{
// ...
}
#GetMapping(value = "/api/agb/check")
#PreAuthorize("hasAnyAuthority('ROLE_USER','ROLE_ADMIN','ROLE_SYSADMIN')")
public SomeDto doSomeotherthing()
{
// ...
}
#GetMapping(value = "/api/agb")
#PreAuthorize("hasAnyAuthority('ROLE_ADMIN','ROLE_SYSADMIN')")
public List<SomeDto> getAll()
{
// ...
}
The "advantage" of this pattern is the centralized control flow, is said. But, isn´t it the case that object-oriented design is about distributing responsibilities and therefore getting rid of such centralized control flow?
Is there a more object-oriented design alternative to the front controller pattern when handling web requests?

Is there a complete JUnit 5 extension example that demonstrates the proper way to maintain state (e.g. WebServerExtension.java from guide)

The main WebServerExtension example from the JUnit5 manual is incomplete and it doesn't fully show how to properly store the configuration (e.g. enableSecurity, server url).
https://github.com/junit-team/junit5/blob/master/documentation/src/main/java/example/registration/WebServerExtension.java
The example ignores or hard codes the values. The manual (section 5.11. Keeping State in Extensions) implies that the "Store" should be used but the ExtensionContext is not yet available yet when the object is constructed -- its not clear how to handle migrating this data to the Store as the ExtensionContext is not yet available in the constructor.
Also its not clear to me that using the Store API for the WebServerExtension programmatic example is even desirable and perhaps it could work just using the internal state (e.g. this.serverUrl, this.enableSecurity, etc.).
Maybe the Store is more applicable to Extensions which don't use this "programmatic" style where multiple instances of the custom extension may exist (appropriately)? In other words its not clear to me from the guide if this a supported paradigm or not?
Other JUnit 5 extension examples online (e.g. org.junit.jupiter.engine.extension.TempDirectory) show how to leverage annotations to handle passing configuration info to the Store but it would be nice if there were a complete programmatic builder type example like WebServerExtension too.
Examples like TempDirectory clearly have access to the ExtensionContext from the beforeXXX() methods whereas the WebServerExtension example does not.
Using the following approach below seems to work fine but I wanted confirmation that this is a supported paradigm (i.e. using fields instead of Stores when using this programmatic approach).
public class WebServerExtension implements BeforeAllCallback {
private final boolean securityEnabled;
private final String serverUrl;
public WebServerExtension(Builder builder) {
this.securityEnabled = builder.enableSecurity;
this.serverUrl = build.serverUrl;
}
#Override
public void beforeAll(ExtensionContext context) {
// is it ok to use this.securityEnabled, this.serverUrl instead of Store API???
}
public String getServerUrl() {
return this.serverUrl;
}
public boolean isSecurityEnabled() {
return this.securityEnabled;
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
private boolean enableSecurity;
private String serverUrl;
public Builder enableSecurity(boolean b) {
this.enableSecurity = b;
return this;
}
public Builder serverUrl(String url) {
this.serverUrl = url;
return this;
}
public WebServerExtension build() {
return new WebServerExtension(this);
}
}
}
Thanks!

Repository OO Design - Multiple Specifications

I have a pretty standard repository interface:
public interface IRepository<TDomainEntity>
where TDomainEntity : DomainEntity, IAggregateRoot
{
TDomainEntity Find(Guid id);
void Add(TDomainEntity entity);
void Update(TDomainEntity entity);
}
We can use various infrastructure implementations in order to provide default functionality (e.g. Entity Framework, DocumentDb, Table Storage, etc). This is what the Entity Framework implementation looks like (without any actual EF code, for simplicity sake):
public abstract class EntityFrameworkRepository<TDomainEntity, TDataEntity> : IRepository<TDomainEntity>
where TDomainEntity : DomainEntity, IAggregateRoot
where TDataEntity : class, IDataEntity
{
protected IEntityMapper<TDomainEntity, TDataEntity> EntityMapper { get; private set; }
public TDomainEntity Find(Guid id)
{
// Find, map and return entity using Entity Framework
}
public void Add(TDomainEntity item)
{
var entity = EntityMapper.CreateFrom(item);
// Insert entity using Entity Framework
}
public void Update(TDomainEntity item)
{
var entity = EntityMapper.CreateFrom(item);
// Update entity using Entity Framework
}
}
There is a mapping between the TDomainEntity domain entity (aggregate) and the TDataEntity Entity Framework data entity (database table). I will not go into detail as to why there are separate domain and data entities. This is a philosophy of Domain Driven Design (read about aggregates). What's important to understand here is that the repository will only ever expose the domain entity.
To make a new repository for, let's say, "users", I could define the interface like this:
public interface IUserRepository : IRepository<User>
{
// I can add more methods over and above those in IRepository
}
And then use the Entity Framework implementation to provide the basic Find, Add and Update functionality for the aggregate:
public class UserRepository : EntityFrameworkRepository<Stop, StopEntity>, IUserRepository
{
// I can implement more methods over and above those in IUserRepository
}
The above solution has worked great. But now we want to implement deletion functionality. I have proposed the following interface (which is an IRepository):
public interface IDeleteableRepository<TDomainEntity>
: IRepository<TDomainEntity>
{
void Delete(TDomainEntity item);
}
The Entity Framework implementation class would now look something like this:
public abstract class EntityFrameworkRepository<TDomainEntity, TDataEntity> : IDeleteableRepository<TDomainEntity>
where TDomainEntity : DomainEntity, IAggregateRoot
where TDataEntity : class, IDataEntity, IDeleteableDataEntity
{
protected IEntityMapper<TDomainEntity, TDataEntity> EntityMapper { get; private set; }
// Find(), Add() and Update() ...
public void Delete(TDomainEntity item)
{
var entity = EntityMapper.CreateFrom(item);
entity.IsDeleted = true;
entity.DeletedDate = DateTime.UtcNow;
// Update entity using Entity Framework
// ...
}
}
As defined in the class above, the TDataEntity generic now also needs to be of type IDeleteableDataEntity, which requires the following properties:
public interface IDeleteableDataEntity
{
bool IsDeleted { get; set; }
DateTime DeletedDate { get; set; }
}
These properties are set accordingly in the Delete() implementation.
This means that, IF required, I can define IUserRepository with "deletion" capabilities which would inherently be taken care of by the relevant implementation:
public interface IUserRepository : IDeleteableRepository<User>
{
}
Provided that the relevant Entity Framework data entity is an IDeleteableDataEntity, this would not be an issue.
The great thing about this design is that I can start granualising the repository model even further (IUpdateableRepository, IFindableRepository, IDeleteableRepository, IInsertableRepository) and aggregate repositories can now expose only the relevant functionality as per our specification (perhaps you should be allowed to insert into a UserRepository but NOT into a ClientRepository). Further to this, it specifies a standarised way in which certain repository actions are done (i.e. the updating of IsDeleted and DeletedDate columns will be universal and are not at the hand of the developer).
PROBLEM
A problem with the above design arises when I want to create a repository for some aggregate WITHOUT deletion capabilities, e.g:
public interface IClientRepository : IRepository<Client>
{
}
The EntityFrameworkRepository implementation still requires TDataEntity to be of type IDeleteableDataEntity.
I can ensure that the client data entity model does implement IDeleteableDataEntity, but this is misleading and incorrect. There will be additional fields that are never updated.
The only solution I can think of is to remove the IDeleteableDataEntity generic condition from TDataEntity and then cast to the relevant type in the Delete() method:
public abstract class EntityFrameworkRepository<TDomainEntity, TDataEntity> : IDeleteableRepository<TDomainEntity>
where TDomainEntity : DomainEntity, IAggregateRoot
where TDataEntity : class, IDataEntity
{
protected IEntityMapper<TDomainEntity, TDataEntity> EntityMapper { get; private set; }
// Find() and Update() ...
public void Delete(TDomainEntity item)
{
var entity = EntityMapper.CreateFrom(item);
var deleteableEntity = entity as IDeleteableEntity;
if(deleteableEntity != null)
{
deleteableEntity.IsDeleted = true;
deleteableEntity.DeletedDate = DateTime.UtcNow;
entity = deleteableEntity;
}
// Update entity using Entity Framework
// ...
}
}
Because ClientRepository does not implement IDeleteableRepository, there will be no Delete() method exposed, which is good.
QUESTION
Can anyone advise of a better architecture which leverages the C# typing system and does not involve the hacky cast?
Interestly enough, I could do this if C# supported multiple inheritance (with separate concrete implementation for finding, adding, deleting, updating).
I do think that you're complicating things a bit too much trying to get the most generic solution of them all, however I think there's a pretty easy solution to your current problem.
TDataEntity is a persistence data structure, it has no Domain value and it's not known outside the persistence layer. So it can have fields it won't ever use, the repository is the only one knowing that, it'a persistence detail . You can afford to be 'sloppy' here, things aren't that important at this level.
Even the 'hacky' cast is a good solution because it's in one place and a private detail.
It's good to have clean and maintainable code everywhere, however we can't afford to waste time coming up with 'perfect' solutions at every layer. Personally, for view and persistence models I prefer the quickest and simplest solutions even if they're a bit smelly.
P.S: As a thumb rule, generic repository interfaces are good, generic abstract repositories not so much (you need to be careful) unless you're serializing things or using a doc db.

adapter-Any real example of Adapter Pattern [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 2 years ago.
Improve this question
I want to demonstrate use of Adapter Pattern to my team. I've read many books and articles online. Everyone is citing an example which are useful to understand the concept (Shape, Memory Card, Electronic Adapter etc.), but there is no real case study.
Can you please share any case study of Adapter Pattern?
p.s. I tried searching existing questions on stackoverflow, but did not find the answer so posting it as a new question. If you know there's already an answer for this, then please redirect.
Many examples of Adapter are trivial or unrealistic (Rectangle vs. LegacyRectangle, Ratchet vs. Socket, SquarePeg vs RoundPeg, Duck vs. Turkey). Worse, many don't show multiple Adapters for different Adaptees (someone cited Java's Arrays.asList as an example of the adapter pattern). Adapting an interface of only one class to work with another seems a weak example of the GoF Adapter pattern. This pattern uses inheritance and polymorphism, so one would expect a good example to show multiple implementations of adapters for different adaptees.
The best example I found is in Chapter 26 of Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development (3rd Edition). The following images are from the instructor material provided on an FTP site for the book.
The first one shows how an application can use multiple implementations (adaptees) that are functionally similar (e.g., tax calculators, accounting modules, credit authorization services, etc.) but have different APIs. We want to avoid hard-coding our domain-layer code to handle the different possible ways to calculate tax, post sales, authorize credit card requests, etc. Those are all external modules that might vary, and for which we can't modify the code. The adapter allows us to do the hard-coding in the adapter, whereas our domain-layer code always uses the same interface (the IWhateverAdapter interface).
We don't see in the above figure the actual adaptees. However, the following figure shows how a polymorphic call to postSale(...) in the IAccountingAdapter interface is made, which results in a posting of the sale via SOAP to an SAP system.
How to turn a french person into a normal person...
public interface IPerson
{
string Name { get; set; }
}
public interface IFrenchPerson
{
string Nom { get; set; }
}
public class Person : IPerson
{
public string Name { get; set; }
}
public class FrenchPerson : IFrenchPerson
{
public string Nom { get; set; }
}
// that is a service that we want to use with our French person
// we cannot or don't want to change the service contract
// therefore we need 'l'Adaptateur'
public class PersonService
{
public void PrintName(IPerson person)
{
Debug.Write(person.Name);
}
}
public class FrenchPersonAdapter : IPerson
{
private readonly IFrenchPerson frenchPerson;
public FrenchPersonAdapter(IFrenchPerson frenchPerson)
{
this.frenchPerson = frenchPerson;
}
public string Name
{
get { return frenchPerson.Nom; }
set { frenchPerson.Nom = value; }
}
}
Example
var service = new PersonService();
var person = new Person();
var frenchPerson = new FrenchPerson();
service.PrintName(person);
service.PrintName(new FrenchPersonAdapter(frenchPerson));
Convert an Interface into another Interface.
Any real example of Adapter Pattern
In order to connect power, we have different interfaces all over the world.
Using Adapter we can connect easily like wise.
Here is an example that simulates converting analog data to digit data.
It provides an adapter that converts float digit data to binary data, it's probably not useful in real world, it just helps to explain the concept of adapter pattern.
Code
AnalogSignal.java
package eric.designpattern.adapter;
public interface AnalogSignal {
float[] getAnalog();
void setAnalog(float[] analogData);
void printAnalog();
}
DigitSignal.java
package eric.designpattern.adapter;
public interface DigitSignal {
byte[] getDigit();
void setDigit(byte[] digitData);
void printDigit();
}
FloatAnalogSignal.java
package eric.designpattern.adapter;
import java.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FloatAnalogSignal implements AnalogSignal {
private Logger logger = LoggerFactory.getLogger(this.getClass());
private float[] data;
public FloatAnalogSignal(float[] data) {
this.data = data;
}
#Override
public float[] getAnalog() {
return data;
}
#Override
public void setAnalog(float[] analogData) {
this.data = analogData;
}
#Override
public void printAnalog() {
logger.info("{}", Arrays.toString(getAnalog()));
}
}
BinDigitSignal.java
package eric.designpattern.adapter;
import java.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class BinDigitSignal implements DigitSignal {
private Logger logger = LoggerFactory.getLogger(this.getClass());
private byte[] data;
public BinDigitSignal(byte[] data) {
this.data = data;
}
#Override
public byte[] getDigit() {
return data;
}
#Override
public void setDigit(byte[] digitData) {
this.data = digitData;
}
#Override
public void printDigit() {
logger.info("{}", Arrays.toString(getDigit()));
}
}
AnalogToDigitAdapter.java
package eric.designpattern.adapter;
import java.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* <p>
* Adapter - convert analog data to digit data.
* </p>
*
* #author eric
* #date Mar 8, 2016 1:07:00 PM
*/
public class AnalogToDigitAdapter implements DigitSignal {
public static final float DEFAULT_THRESHOLD_FLOAT_TO_BIN = 1.0f; // default threshold,
private Logger logger = LoggerFactory.getLogger(this.getClass());
private AnalogSignal analogSignal;
private byte[] digitData;
private float threshold;
private boolean cached;
public AnalogToDigitAdapter(AnalogSignal analogSignal) {
this(analogSignal, DEFAULT_THRESHOLD_FLOAT_TO_BIN);
}
public AnalogToDigitAdapter(AnalogSignal analogSignal, float threshold) {
this.analogSignal = analogSignal;
this.threshold = threshold;
this.cached = false;
}
#Override
public synchronized byte[] getDigit() {
if (!cached) {
float[] analogData = analogSignal.getAnalog();
int len = analogData.length;
digitData = new byte[len];
for (int i = 0; i < len; i++) {
digitData[i] = floatToByte(analogData[i]);
}
}
return digitData;
}
// not supported, should set the inner analog data instead,
#Override
public void setDigit(byte[] digitData) {
throw new UnsupportedOperationException();
}
public synchronized void setAnalogData(float[] analogData) {
invalidCache();
this.analogSignal.setAnalog(analogData);
}
public synchronized void invalidCache() {
cached = false;
digitData = null;
}
#Override
public void printDigit() {
logger.info("{}", Arrays.toString(getDigit()));
}
// float -> byte convert,
private byte floatToByte(float f) {
return (byte) (f >= threshold ? 1 : 0);
}
}
Code - Test case
AdapterTest.java
package eric.designpattern.adapter.test;
import java.util.Arrays;
import junit.framework.TestCase;
import org.junit.Test;
import eric.designpattern.adapter.AnalogSignal;
import eric.designpattern.adapter.AnalogToDigitAdapter;
import eric.designpattern.adapter.BinDigitSignal;
import eric.designpattern.adapter.DigitSignal;
import eric.designpattern.adapter.FloatAnalogSignal;
public class AdapterTest extends TestCase {
private float[] analogData = { 0.2f, 1.4f, 3.12f, 0.9f };
private byte[] binData = { 0, 1, 1, 0 };
private float[] analogData2 = { 1.2f, 1.4f, 0.12f, 0.9f };
#Test
public void testAdapter() {
AnalogSignal analogSignal = new FloatAnalogSignal(analogData);
analogSignal.printAnalog();
DigitSignal digitSignal = new BinDigitSignal(binData);
digitSignal.printDigit();
// adapter
AnalogToDigitAdapter adAdapter = new AnalogToDigitAdapter(analogSignal);
adAdapter.printDigit();
assertTrue(Arrays.equals(digitSignal.getDigit(), adAdapter.getDigit()));
adAdapter.setAnalogData(analogData2);
adAdapter.printDigit();
assertFalse(Arrays.equals(digitSignal.getDigit(), adAdapter.getDigit()));
}
}
Dependence - via maven
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.13</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.13</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
How to test
Just run the unit test.
Adapter pattern works as a bridge between two incompatible interfaces.
This pattern involves a single class called adapter which is
responsible for communication between two independent or incompatible
interfaces.
Real-world examples might be a language translator or a mobile charger. More here in this youtube video:
Youtube - Adapter Design pattern: Introduction
You can use the Adapter design pattern when you have to deal with different interfaces with similar behavior (which usually means classes with similar behavior but with different methods). An example of it would be a class to connect to a Samsung TV and another one to connect to a Sony TV. They will share common behavior like open menu, start playback, connect to a network and etc but each library will have a different implementation of it (with different method names and signatures). These different vendor specific implementations are called Adaptee in the UML diagrams.
So, in your code (called Client in the UML diagrams), instead of hard code the method calls of each vendor (or Adaptee), you could then create a generic interface (called Target in UML diagrams) to wrap these similar behaviors and work with only one type of object.
The Adapters will then implement the Target interface delegating its method calls to the Adaptees that are passed to the Adapters via constructor.
For you to realize this in Java code, I wrote a very simple project using exactly the same example mentioned above using adapters to deal with multiple smart TV interfaces. The code is small, well documented and self explanatory so dig on it to see how a real world implementation would look like.
Just download the code and import it to Eclipse (or your favorite IDE) as a Maven project. You can execute the code by running org.example.Main.java. Remember that the important thing here is to understand how classes and interfaces are assembled together to design the pattern. I also created some fake Adaptees in the package com.thirdparty.libs. Hope it helps!
https://github.com/Dannemann/java-design-patterns
Adapter design patterns helps in converting interface of one class into interface of client expects.
Example:
You have a service which returns weather (in celsius) by passing city name as a input value. Now, assume that your client wants to pass zipcode as input and expecting the temperature of the city in return. Here you need an adaptor to achieve this.
public interface IWetherFinder {
public double getTemperature(String cityName);
}
class WeatherFinder implements IWetherFinder{
#Override
public double getTemperature(String cityName){
return 40;
}
}
interface IWeatherFinderClient
{
public double getTemperature(String zipcode);
}
public class WeatherAdapter implements IWeatherFinderClient {
#Override
public double getTemperature(String zipcode) {
//method to get cityname by zipcode
String cityName = getCityName(zipcode);
//invoke actual service
IWetherFinder wetherFinder = new WeatherFinder();
return wetherFinder.getTemperature(cityName);
}
private String getCityName(String zipCode) {
return "Banaglore";
}
}
One Real example is Qt-Dbus.
The qt-dbus has a utility to generate the adaptor and interface code from the xml file provided. Here are the steps to do so.
1. Create the xml file - this xml file should have the interfaces
that can be viewed by the qdbus-view in the system either on
the system or session bus.
2.With the utility - qdbusxml2cpp , you generate the interface adaptor code.
This interface adaptor does the demarshalling of the data that is
received from the client. After demarshalling, it invokes the
user defined - custom methods ( we can say as adaptee).
3. At the client side, we generate the interface from the xml file.
This interface is invoked by the client. The interface does the
marshalling of the data and invokes the adaptor interface. As told
in the point number 2, the adaptor interface does the demarshalling
and calls the adaptee - user defined methods.
You can see the complete example of Qt-Dbus over here -
http://www.tune2wizard.com/linux-qt-signals-and-slots-qt-d-bus/
Use Adapter when you have an interface you cannot change, but which you need to use. See it as you're the new guy in an office and you can't make the gray-hairs follow your rules - you must adapt to theirs. Here is a real example from a real project I worked on sometime where the user interface is a given.
You have an application that read all the lines in a file into a List data structure and displayed them in a grid (let's call the underlying data store interface IDataStore). The user can navigate through these data by clicking the buttons "First page", "Previous page", "Next page", "Last Page". Everything works fine.
Now the application needs to be used with production logs which are too big to read into memory but the user still needs to navigate through it! One solution would be to implement a Cache that stores the first page, next, previous and last pages. What we want is when the user clicks "Next page", we return the page from the cache and update the cache; when they click last page, we return last page from cache. In the background we have a filestream doing all the magic. By so doing we only have four pages in memory as opposed to the entire file.
You can use an adapter to add this new cache feature to your application without the user noticing it. We extend the current IDataStore and call it CacheDataStore. If the file to load is big, we use CacheDataStore. When we make a request for First, Next, Previous and Last pages, the information is routed to our Cache.
And who knows, tomorrow the boss wants to start reading the files from a database table. All you do is still extend IDataStore to SQLDataStore as you did for Cache, setup the connection in the background. When they click Next page, you generate the necessary sql query to fetch the next couple hundred rows from the database.
Essentially, the original interface of the application did not change. We simply adapted modern and cool features to work it while preserving the legacy interface.
You can find a PHP implementation of the Adapter pattern used as a defense against injection attacks here:
http://www.php5dp.com/category/design-patterns/adapter-composition/
One of the interesting aspects of the Adapter pattern is that it comes in two flavors: A class adapter relying on multiple inheritance and an object adapter relying on composition. The above example relies on composition.
#Justice o's example does not talk about adapter pattern clearly. Extending his answer -
We have existing interface IDataStore that our consumer code uses and we cannot change it. Now we are asked to use a cool new class from XYZ library that does what we want to implement, but but but, we cannot change that class to extend our IDataStore, seen the problem already ?
Creating a new class - ADAPTER, that implements interface our consumer code expects, i.e. IDataStore and by using class from the library whose features we need to have - ADAPTEE, as a member in our ADAPTER, we can achieve what we wanted to.
As per “C# 3.0 Design Patterns” book by Judith Bishop, Apple used Adapter pattern to adapt Mac OS to work with Intel products (explained in Chapter # 4, excerpt here2)
C# 3.0 Design Patterns
Structural Patterns: Adapter and Façade
An example from Yii framework would be: Yii uses internally cache utilizing an interface
ICache.
https://www.yiiframework.com/doc/api/1.1/ICache
whose signature is like : -
abstract public boolean set(string $id, mixed $value, integer $expire=0, ICacheDependency $dependency=NULL)
abstract public mixed get(string $id)
Let's say, you would like to use inside a Yii project the symfony cache library
https://packagist.org/packages/symfony/cache with it's cache interface, by defining this service in Yii services components (service locator) configuration
https://github.com/symfony/cache-contracts/blob/master/CacheInterface.php
public function get(string $key, callable $callback, float $beta = null, array &$metadata = null);
We see, symfony cache has an interface with only a get method, missing a set method and a different signature for a get method, as Symfony uses the get method also as a setter when supplying the second callable parameter.
As Yii core internally uses this Yii cache/interface, it's difficult (extending Yii/YiiBase) if not impossible at places , to rewrite the calls to that interface.
Plus Symfony cache is nor our class, so we can't rewrite it's interface to fit with the Yii cache interface.
So here comes the adapter pattern to rescue. We will write a mapping = an intermediate adapter which will map the Yii cache interface calls to Symfony cache interface
Would look like this
class YiiToSymfonyCacheAdapter implements \Yii\system\caching\ICache
{
private \Symfony\Contracts\Cache\CacheInterface $symfonyCache;
public function __construct(\Symfony\Contracts\Cache\CacheInterface $symfonyCache)
{
$this->symfonyCache = $symfonyCache;
}
public boolean set(string $id, mixed $value, integer $expire=0, ICacheDependency
$dependency=NULL)
{
// https://symfony.com/doc/current/cache.html
return $this->symfonyCache->get(
$id,
function($item) {
// some logic ..
return $value;
}
);
// https://github.com/symfony/cache/blob/master/Adapter/MemcachedAdapter.php
// if a class could be called statically, the adapter could call statically also eg. like this
// return \Symfony\Component\Cache\Adapter\MemcacheAdapter::get(
// $id,
// function($item) {
// // some logic ..
// return $value;
// }
);
}
public mixed get(string $id)
{
// https://github.com/symfony/cache/blob/master/Adapter/FilesystemAdapter.php
// if a class could be called statically, the adapter could call statically also eg. like this
// \Symfony\Component\Cache\Adapter\FileSystemAdapter::get($id)
return $this->symfonyCache->get($id)
}
}
A real example can be reporting documents in an application. Simple code as here.
Adapters i think are very useful for programming structure.
class WordAdaptee implements IReport{
public void report(String s) {
System.out.println(s +" Word");
}
}
class ExcellAdaptee implements IReport{
public void report(String s) {
System.out.println(s +" Excel");
}
}
class ReportAdapter implements IReport{
WordAdaptee wordAdaptee=new WordAdaptee();
#Override
public void report(String s) {
wordAdaptee.report(s);
}
}
interface IReport {
public void report(String s);
}
public class Main {
public static void main(String[] args) {
//create the interface that client wants
IReport iReport=new ReportAdapter();
//we want to write a report both from excel and world
iReport.report("Trial report1 with one adaptee"); //we can directly write the report if one adaptee is avaliable
//assume there are N adaptees so it is like in our example
IReport[] iReport2={new ExcellAdaptee(),new WordAdaptee()};
//here we can use Polymorphism here
for (int i = 0; i < iReport2.length; i++) {
iReport2[i].report("Trial report 2");
}
}
}
Results will be:
Trial report1 with one adaptee Word
Trial report 2 Excel
Trial report 2 Word
This is an example of adapter implementation:
interface NokiaInterface {
chargementNokia(x:boolean):void
}
class SamsungAdapter implements NokiaInterface {
//nokia chargement adapted to samsung
chargementNokia(x:boolean){
const old= new SamsungCharger();
let y:number = x ? 20 : 1;
old.charge(y);
}
}
class SamsungCharger {
charge(x:number){
console.log("chrgement x ==>", x);
}
}
function main() {
//charge samsung with nokia charger
const adapter = new SamsungAdapter();
adapter.chargementNokia(true);
}