适配器模式
将一个类的接口转换成客户期望的另一个接口,使得原本接口不兼容的类可以一起工作。
适合的场景
你想用的类接口和现有代码不匹配,直接用会报错、跑不通,怎么办?
比如:
新旧系统接口不同,要桥接起来
第三方库的接口和你写的代码风格差别大
不想修改现有代码,只想包一层转换层
GDScript和C#的跨语言调用
适配器就像个插头转换器,帮你把接口“插口”对齐,让它们和谐共处!
基本结构
目标接口(Target):客户端需要的接口。
需要适配的类(Adaptee):接口不兼容但功能需要使用的类。
适配器(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()