如何使用无共同父类且不可修改的两个近乎相同第三方类?
解决无共同父类的第三方类统一调用问题
这种场景真的太头疼了——第三方库的类逻辑相似但没统一父类,还不能改源码,用instanceof堆判断又会让代码臃肿不堪,改起来要改N处。别慌,适配器模式完美适配这个需求,既能统一调用逻辑,又不用碰原类的代码,还能避免重复。
步骤1:定义统一的接口
先给所有动物定义一个统一的行为标准,也就是我们理想中的Animal接口,把需要的方法都列进去:
public interface Animal { void speak(); Object findFood(); // 因为CatFood和DogFood是不同类,用Object兼容;如果能给食物也抽象接口会更优雅 void eat(Object food); }
要是CatFood和DogFood能有统一抽象(哪怕是我们自己定义的空接口Food),可以把上面的Object换成Food,类型安全性会更高。
步骤2:编写适配器类
给Cat和Dog分别写适配器,把它们的方法适配到Animal接口上,相当于给它们套个统一的“外壳”:
CatAdapter
public class CatAdapter implements Animal { private Cat cat; public CatAdapter(Cat cat) { this.cat = cat; } @Override public void speak() { cat.speak(); } @Override public Object findFood() { return cat.findFood(); } @Override public void eat(Object food) { // 这里强转是安全的,因为适配器包装的是Cat,传入的必然是CatFood cat.eat((CatFood) food); } }
DogAdapter
public class DogAdapter implements Animal { private Dog dog; public DogAdapter(Dog dog) { this.dog = dog; } @Override public void speak() { dog.speak(); } @Override public Object findFood() { return dog.findFood(); } @Override public void eat(Object food) { dog.eat((DogFood) food); } }
步骤3:统一调用
现在就可以像你理想中的那样使用了,把原对象包装成适配器,放进Animal数组循环调用:
public class Main { public static void main(String[] args) { Animal[] animals = {new CatAdapter(new Cat()), new DogAdapter(new Dog())}; for (Animal animal : animals) { animal.speak(); animal.eat(animal.findFood()); } } }
为什么这比instanceof好?
- 无重复代码:所有调用逻辑都在循环里写一次,新增动物(比如Rabbit)只需要加一个
RabbitAdapter,不用修改循环的代码,完全符合开闭原则。 - 解耦:原类和调用逻辑分开,原类更新只需要调整对应的适配器,不会影响整体调用流程。
- 代码更干净:再也不用堆一堆
if-else instanceof的判断,代码可读性和维护性直接拉满。
如果后续要加更多动物,只需要重复适配器的套路就行,零重复的调用逻辑。
内容的提问来源于stack exchange,提问作者mchen
相关产品推荐
相关产品推荐

