Skip to content

适配器模式

将一个类的接口转换成客户期望的另一个接口,使得原本接口不兼容的类可以一起工作。

适合的场景

你想用的类接口和现有代码不匹配,直接用会报错、跑不通,怎么办?

比如:

  • 新旧系统接口不同,要桥接起来

  • 第三方库的接口和你写的代码风格差别大

  • 不想修改现有代码,只想包一层转换层

  • GDScript和C#的跨语言调用

适配器就像个插头转换器,帮你把接口“插口”对齐,让它们和谐共处!

基本结构

  1. 目标接口(Target):客户端需要的接口。

  2. 需要适配的类(Adaptee):接口不兼容但功能需要使用的类。

  3. 适配器(Adapter):实现目标接口,内部调用适配者的方法,完成接口转换。

示例

csharp
// 目标接口
public interface ITarget
{
    void Request();
}

// 需要适配的类(接口不匹配)
public class Adaptee
{
    public void SpecificRequest()
    {
        Console.WriteLine("Adaptee的特殊请求");
    }
}

// 适配器,将Adaptee转换成ITarget
public class Adapter : ITarget
{
    private Adaptee _adaptee;

    public Adapter(Adaptee adaptee)
    {
        _adaptee = adaptee;
    }

    public void Request()
    {
        // 转换调用
        _adaptee.SpecificRequest();
    }
}

// 使用
Adaptee adaptee = new Adaptee();
ITarget target = new Adapter(adaptee);
target.Request();

适配器模式也非常适合跨语言交互,将另一个语言适配到当前语言

gdscript
extends Resource  

var keyword: String:         
    get:
        return "add"    
var parameter_types: Array[Variant.Type]:
    get:
        return [TYPE_INT, TYPE_INT]    

func execute(args: Array) -> void:         
    print(args[0] + args[1])
csharp
public interface IConsoleCommand
{
    string Keyword { get; }
    Variant.Type[] ParameterTypes { get; }
    void Execute(Godot.Collections.Array parameters);
}

public class GDScriptCommandWrapper(GDScript script) : IConsoleCommand
{
    private readonly GodotObject _instance = script.New().AsGodotObject();

    public string Keyword => _instance.HasMethod("get_keyword")
        ? _instance.Call("get_keyword").As<string>()
        : _instance.Get("keyword").As<string>();

    public Variant.Type[] ParameterTypes => _instance.HasMethod("get_parameter_types")
        ? _instance.Call("get_parameter_types").AsGodotArray<Variant.Type>().ToArray()
        : _instance.Get("parameter_types").AsGodotArray<Variant.Type>().ToArray();

    public void Execute(Godot.Collections.Array args) => _instance.Call("execute", args);
}

GDScript 示例

gdscript
# 目标接口
class Target:

    func request():
        pass

# 需要适配的类
class Adaptee:

    func specific_request():
        print("Adaptee的特殊请求!")

# 适配器
class Adapter extends Target:

    var adaptee := Adaptee.new()

    func request():
        adaptee.specific_request()
        
# 使用
func _ready():
    var adapter = Adapter.new()
    adapter.request()