适配器模式
描述:
适配器模式的出现是为了解决扩展接口时,在不更改现有的代码的基础上,让一个接口拥有另一个接口的功能或者让现有的接口兼容新系统或者接口的规范。两个独立接口之前通过适配器类来建立调用关系,在扩展了接口的基础上,对现有代码的影响尽可能的小。
常用场景:
类似于中国移动的SIM卡在不同手机中的使用对其大小和规格也有不同的要求,因此中国移动的电话卡支持在卡的外部进行边框的安装和拆除,在老年机中用的是最大的边框,在智能机中用的是中等边框,在苹果手机中用的是最小边框。这个场景中,SIM卡中的最小的那片就相当于系统的现有类,大小不等的边框就相当于适配器类,不同的手机就相当于不同的系统的要求,更换边框也就是适配器的操作让SIM卡最终满足不同机型也就是系统的需求,只不过这个例子中SIM卡的功能是一样的,在实际开发场景中,可能会对现有类进行扩展以让它支持新的功能。
项目结构:
实现:
1.创建MyGym体育馆接口,该接口拥有一个做运动的方法。
/**
* @author Carl
* @version 1.0
* @date 2020/8/17 14:44
* @description
**/
public interface MyGym {
public void doSports(String name,String msg);
}
2.创建SwimmingPool游泳池类实现MyGym接口
/**
* @author Carl
* @version 1.0 Gym的实现类,我们具体需要调用的实现类
* @date 2020/8/17 14:49
* @description
**/
public class SwimmingPool implements MyGym {
@Override
public void doSports(String name ,String msg) {
SportAdaptor sportAdaptor = new SportAdaptor();
if("swim".equals(name)){
System.out.println("start swim "+msg);
}else if("basketball".equals(name) || "football".equals(name)){
sportAdaptor.doSports(name,msg);
}else {
System.out.println("I can't do this!");
}
}
}
3.创建Ballplace球场接口类,该类有一个做运动的方法
/**
* @author Carl
* @version 1.0
* @date 2020/8/24 16:35
* @description
**/
public interface BallPlace {
void doSports(String name,String msg);
}
4.创建BastketBallPlace篮球场类实现球场类
/**
* @author Carl
* @version 1.0 扩展功能的实现类
* @date 2020/8/24 16:36
* @description
**/
public class BasketballPlace implements BallPlace {
@Override
public void doSports(String name,String msg) {
System.out.println("start Basketball "+msg);
}
}
5.创建FootballPlace足球场类实现球场类
/**
* @author Carl
* @version 1.0 扩展功能的实现类
* @date 2020/8/24 16:38
* @description
**/
public class FootballPlace implements BallPlace{
@Override
public void doSports(String name, String msg) {
System.out.println("start Football "+msg);
}
}
6.创建SportAdaptor运动适配器类实现MyGym类
/**
* @author Carl
* @version 1.0 桥接模式最重要的调用类
* @date 2020/8/17 14:53
* @description
**/
public class SportAdaptor implements MyGym{
@Override
public void doSports(String name, String msg) {
if("basketball".equals(name)){
BasketballPlace basketballPlace = new BasketballPlace();
basketballPlace.doSports(name,msg);
}else if("football".equals(name)){
FootballPlace footballPlace = new FootballPlace();
footballPlace.doSports(name, msg);
}
}
}
7.测试类
/**
* @author Carl
* @version 1.0
* @date 2020/8/29 9:51
* @description
**/
public class Domian {
public static void main(String[] args) {
SwimmingPool swimmingPool = new SwimmingPool();
swimmingPool.doSports("football","happy");
swimmingPool.doSports("basketball","sad");
swimmingPool.doSports("swim","exciting");
}
}
8.测试结果
start Football happy
start Basketball sad
start swim exciting
说明:
1.MyGym类和Swimming类相当于就是系统现有的类,Swimming类提供游泳的功能
2.BallPlace类、BasketballPlace类、FootballPlace类相当于系统另外几个拥有打篮球和踢足球功能的类
3.现在要求说想在Swimming类也就是游泳池边上打球,听起来可能很荒谬,但是实际开发过程中谁也不知道需求方会有什么天马行空的想法。这种情况下就需要文中的SportAdaptor适配器类,该适配器类实现MyGym接口类,但是在具体方法中引用的是BallPlace接口的功能,以达到对游泳池类功能扩展的效果
4.可以看到,在测试类中虽然外部调用的都是Swimming类的方法,实际上第一第二个方法在内部调用的是另两个类的功能了。因此适配器类也存在一个问题,其内部实现对于调用者是相对封闭的,在调用这个类或者方法的时候实际上可能调用的是其他的接口或者方法,如果大量使用适配器类来完成类似的操作,对于后期系统维护和代码的理解上会存在很大的问题