适配器模式
适配器模式是一种结构型模式,它可以时原本不兼容的接口,互相工作。
比方说,生活中常见的数据线转接口,由于插口不同,有的ios,有的type-c,但使用一样,所以我们可以使用适配器。
适配器模式主要是通过创建适配器类,作用是能够转换对象接口,使其互相交互。将复杂的转换过程封装到适配器类中。适配器不仅可以将不同接口的对象相互合作,也可以用来转换不同格式的数据。
结构
这里有两种结构表示
- 类适配器 - 通过继承的方式
- 对象适配器 - 通过聚合或组合的方式
说明
- ITarget(目标接口)- 客户端需要的接口,即需要得到的接口
- Adapter(适配器,核心)- 通过继承和聚合的方式,来实现 Adaptee 和 Target 的相互转换。
- Adatee(被适配者)- 被适配的类或接口,本身与客户端需要的接口不兼容, 因此无法直接调用其功能。
不管是通过继承的类适配器模式,还是通过聚合的对象适配器模式,它们的本质是一样的,就是让不兼容的接口,可以互相工作。
实现 - Unity
实现方式主要是这两种
- 类适配器
- 对象适配器
类适配器
public class AdapterExample1 : MonoBehaviour
{
private void Start()
{
IAttack attack = new AttackAdapter();
CharacterAttack(attack);
}
private void CharacterAttack(IAttack attack) => attack.Attack();
}
public class Enemy
{
public void EnemyAttack()
{
Debug.Log("Enemy Attack");
}
}
public interface IAttack
{
void Attack();
}
public class AttackAdapter : Enemy, IAttack
{
public void Attack()
{
EnemyAttack();
}
}
由于类适配器模式,是通过继承的方式来完成的,所以我们可以重写功能来满足需要,但继承这种方式,耦合度很高,也不满足合成复用原则。
对象适配器
public class AdapterExample2 : MonoBehaviour
{
private void Start()
{
Cat cat = new Cat();
Dog dog = new Dog();
ICall adapter = new AnimalCall(cat);
Call(dog);
Call(adapter);
}
public void Call(ICall call) => call.Call();
}
public class Cat
{
public void CatCall()
{
Debug.Log("喵,喵,喵");
}
}
public interface ICall
{
void Call();
}
public class Dog : ICall
{
public void Call()
{
Debug.Log("汪,汪,汪");
}
}
public class AnimalCall : ICall
{
private Cat _cat;
public AnimalCall(Cat cat)
{
_cat = cat;
}
public void Call()
{
_cat.CatCall();
}
}
对象适配器模式是比较常用的一种模式,比如第三方库无法满足项目接口,需要使用适配器进行适配相对于接口。
应用场景
- 当你使用某些类时,但接口不兼容
- 如果您需要复用这样一些类,他们处于同一个继承体系, 并且他们又有了额外的一些共同的方法,但是这些共同的方法不是所有在这一继承体系中的子类所具有的共性
利与弊
优点
- 将复杂的转换过程与业务逻辑分离
- 客户端只需和适配器打交道,无需更改代码,需要适配时,添加新的适配器即可。
缺点
- 代码复杂度升高
对于适配器模式的使用,一般在一些遗留下来的代码或第三方的库,不兼容的情况比较多,一般可以直接修改代码来满足接口的话,建议直接修改代码,而不是去使用适配器模式。 适配器模式在项目后期,有遗留代码的情况,才进行考虑。
🦌🦌🦌🦌🦌🦌🦌🦌🦌🦌🦌🦌🦌🦌🦌🦌🦌🦌🦌🦌🦌🦌🦌🦌🦌🦌🦌🦌🦌🦌🦌