Categories: Design Pattern

Structural Patterns – Adapter

Adapter – Allows unrelated objects with an incompatible interface to collaborate.

From Design Patterns – Structural Patterns

Structure

Class adapter – Class diagram UML
Object adapter – Class diagram UML

Applicability

When the project has some existing class, the interface class isn’t compatible with the rest of the project code.

It is used when the developer wants to reuse a few existing sub-class that lack common functionally and can’t be added by the source code to the sub-classes.

Pros and Cons

PROS

  • Single Responsibility Principle.
  • Open-closed Principle.

CONS

  • It will let the overall code complexity increases because it needs to add the new interfaces and classes. Sometimes, it changes the service class so that it matches the rest of the code.

How to Implement

The adapter patterns have two methods that can implement, such as the object adapter and the class adapter.

#1 Basic Sample

1. Object adapter

static void Main(string[] args)
{
    Adaptee adaptee = new Adaptee();
    ITargert targert = new Target(adaptee);

    Console.WriteLine(targert.GetReuqest());

    Console.ReadKey();
}

public interface ITargert
{
    string GetReuqest();
}

public class Adaptee
{
    public string GetSpecificRequest() => "Specific reuqest";
}

public class Target : ITargert
{
    private readonly Adaptee adaptee;

    public Target(Adaptee _daptee)
    {
 this.adaptee = _daptee;
    }

    public string GetReuqest() => $"This is '{this.adaptee.GetSpecificRequest()}'";
}

2. Class adapter

static void Main(string[] args)
{
    Adaptee adaptee = new Adaptee();
    ITargert targert = new Target();

    Console.WriteLine(targert.GetReuqest(adaptee));

    Console.ReadKey();
}

public interface ITargert
{
    string GetReuqest(Adaptee adaptee);
}

public class Adaptee
{
    public string GetSpecificRequest() => "Specific reuqest";
}

public class Target : ThirdPartyClass, ITargert
{
    public string GetReuqest(Adaptee adaptee) => $"This is '{GetThirdPartRequest(adaptee)}'";
}

public class ThirdPartyClass
{
    public string GetThirdPartRequest(Adaptee adaptee) => adaptee.GetSpecificRequest();
}

#2 Web Application Project

Step 1 Create the generic repository mechanism in the Core project and the Infra project. The interface class file name sets “IAdapter_Obj.” Another interface class file name sets “IAdapter_Class.” The repository class file name sets “AdapteRepo_Obj.” Another repository class file name sets “AdapteRepo_Class.”

Fig 1 Core project & Infra project – Solution explorer

Step 2 Create the new class files called “Adaptee_Obj” and “Adaptee_Class” under the Core project.

  • Adaptee_Obj & Adaptee_Class are same as source code logic.
public class Adaptee_Class<T> where T : class
{
 public IEnumerable<T> CopyToObject(List<T> obj)
 {
  List<T> result = new List<T>();
  result.AddRange(obj);
  result.AddRange(obj);

  return result.ToList();
 }
}

Step 3 AdapterRepo_Obj source code and AdapterRepo_Class source code have a few part differences. The source code shows below:

  • Object adapter – AdapterRepo_Obj
public class AdapterRepo_Obj<T> : IAdapter_Obj<T> where T : class
{
 private readonly Adaptee_Obj<T> adaptee;
 private readonly IGenericTypeRepository<T> repo;

 public AdapterRepo_Obj(IGenericTypeRepository<T> _repo)
 {
  this.adaptee = new Adaptee_Obj<T>();
  this.repo = _repo;
 }

 public IEnumerable<T> GetRequest()
 {
  try
  {
   List<T> obj = repo.GetAll().Result as List<T>;
 
   if (obj.Count != 0)
    return this.adaptee.CopyToObject(obj);
   else
    return new List<T>();
  }
  catch (Exception e)
  {
   return new List<T>();
  }
 }
}
  • Class adapter – AdapterRepo_Class
public class AdapterRepo_Class<T> : Adaptee_Class<T> ,IAdapter_Class<T> where T : class
{
 private readonly IGenericTypeRepository<T> repo;

 public AdapterRepo_Class(IGenericTypeRepository<T> _repo)
 {    
     this.repo = _repo;
 }

 public IEnumerable<T> GetRequest(Adaptee_Class<T> adaptee_Class)
 {
     try
     {
  List<T> obj = repo.GetAll().Result as List<T>;

  if (obj.Count != 0)
      return CopyToObject(obj);
  else
      return new List<T>();
         }
         catch (Exception e)
            {
  return new List<T>();
     }
 }
}

Step 4 Create the new controller file and the view file under the web project. New controller file name sets “AdapterController.” The view part only creates the Index page.

Fig 2 AdapterContrller file source code
Fig 3 Adapter pattern result

Reference

davidsky69

View Comments

Recent Posts

API Gateway in .NET 5 with Ocelot

What is the API gateway? An API gateway is an API management tool that sits…

3 years ago

.NET 5 application with Onion architecture

The .NET 5 SDK is a kind of milestone in the .NET world. The .NET…

4 years ago

SOLID Principles – Dependency inversion principle

In object-oriented design, the dependency inversion principle is a specific methodology for loosely coupling software…

4 years ago

SOLID Principles – Interface segregation principle

In the field of software engineering, the interface segregation principle (ISP) states that no code…

4 years ago

SOLID Principles – Liskov substitution principle

Subtype Requirement: Let  be a property provable about objects  of type T. Then  should be true for objects  of type S where S is…

4 years ago

SOLID Principles – Open-closed principle

In object-oriented programming, the open–closed principle states "software entities (classes, modules, functions, etc.) should be…

4 years ago