STRUCTURAL

Adapter

What Is It?

Adapter is a structural design pattern that allows two incompatible systems to work together. A simple way to think about it is like a power adapter: the plug does not fit the socket directly, so you place an adapter between them and the device works without changing either side.

In software, the idea is the same. Sometimes a class, SDK, or old system does not match the interface your project expects. Instead of changing that external system, you create an Adapter between your code and the incompatible API.

The Adapter implements the interface your system already knows. Inside, it holds the incompatible object and translates calls into a format that object understands. This way, the rest of your code keeps working with the same clean interface and does not need to know what is happening behind the scenes.

For example, your project may expect an ILogger interface, but a third-party logger only has a method like WriteLine(). A LoggerAdapter can implement ILogger, receive Log() calls, and forward them to WriteLine() internally.

When Is It Used?

Adapter is useful when you want to connect a new or incompatible system to your project without rewriting existing code. It is especially helpful when you do not own the source code or when changing the original class would create more problems.

In Unity projects, Adapter is commonly used when integrating third-party SDKs such as ads, analytics, social login, in-app purchases, or audio systems. Instead of spreading SDK-specific code across the project, you can hide it behind your own interface.

It is also useful when working with legacy systems. For example, an old save system may not support your new IDataPersistence interface, so an adapter can make it compatible with the new structure.

Adapter can also help with platform-specific code. iOS and Android plugins may have different APIs, but your game can still communicate with both through a shared interface like IAdsService.

It is also valuable for testing. During tests, you can replace the real SDK with a fake or mock adapter. This makes your code easier to test without depending on real services or plugins.

Animation

Adapter Pattern
LOGS SENT0

Code

Assets / Scripts / Structural / AdapterILogger.cs
READ ONLY
C#
1
2
3
4
5
6
7
namespace Patterns.Structural.Adapter
{
    public interface ILogger
    {
        void Log(string message);
    }
}

Advantages and Disadvantages

• Advantages:

  • Adds new systems without breaking existing code.
  • Reduces direct dependencies.
  • Improves testability.
  • Keeps translation logic in one place.

• Disadvantages:

  • It can increase the number of classes.
  • It can add overhead in hot loops.
  • Overuse can hide weak architecture.

Tips

In Unity, it is usually better to keep adapters as plain C# classes instead of making them MonoBehaviours. This keeps them independent from the scene and easier to test.

Using Adapter together with Dependency Injection is also a good practice. Instead of creating the adapter directly inside Awake(), pass it from the outside when possible.

For platform-specific systems, avoid spreading #if UNITY_IOS and #if UNITY_ANDROID checks across your code. A cleaner approach is to create separate adapters for each platform and use a factory to decide which one should be used.

Be careful when wrapping ScriptableObject-based systems. A ScriptableObject should usually hold data, while the adapter can expose that data through an interface such as IInventoryService.

Avoid long adapter chains. If one adapter keeps calling another, debugging becomes harder and performance may suffer.

When testing, keep the two sides separate. Test your main system with a mock adapter, and test the real SDK or plugin integration separately.