结构型模式
作用:从程序的结构上实现松耦合,从而可以扩大整体的类结构,用来解决更大的问题。
结构型模式有:适配器模式、代理模式、桥接模式、装饰模式、组合模式、外观模式、享元模式。
结构型模式可以分为类结构型模式和对象结构型模式:
类结构型模式关心类的组合,由多个类可以组合成一个更大的系统,在类结构型模式中一般只存在继承关系和实现关系。
对象结构型模式关心类与对象的组合,通过关联关系使得在一个类中定义另一个类的实例对象,然后通过该对象调用其方法。根据“合成复用原则”,在系统中尽量使用关联关系来替代继承关系,因此大部分结构型模式都是对象结构型模式。
适配器模式动机及定义(Adapter Pattern)
现实生活中的USB网线转换器、电脑的充电线(200v--20v)问题;软件开发中自然也会遇到类似的问题,比如存在不兼容的结构,例如方法名不一致等,和现实生活一样,引入适配器的概念。
定义:将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作。(指广义的接口,它可以表示一个方法或者方法的集合)
既可以作为类结构型模式,也可以作为对象结构型模式
角色分析:
目标抽象类(目标接口,客户所期待的接口,目标可以是具体的或抽象的类,也可以是接口)
需要适配的类
适配器(通过包装一个需要适配的对象,把原接口转换成目标对象)
适配器模式适用场所
系统需要使用一些现有的类,而这些类的接口不符合系统的需要,甚至没有这些类的源代码
创建一个可以重复使用的类,用于和一些彼此之间没有太大关联的类,包括一些可能在将来引进的类一起工作
例如SpringMVC和SpringBoot中就有使用到,GUI编程中也用到了大量的适配器
类适配器的实现(用得少)
因为用到了继承,所以不建议使用
首先我们需要创建WiFI类,然后创建客户端类,再编写一个适配器接口,最后写一个具体的适配器类来实现接口和继承WiFi类,具体代码实现如下:
//要被适配的类
public class WiFi {
public void request() {
System.out.println("连接网线上网");
}
}
//客户端类:想上网,插不上网线
public class Computer {
public void net(NetToUsb adapter) {
//上网的具体实现,找一个转接头
adapter.handleRequest();
}
public static void main(String[] args) {
Computer computer = new Computer();
Adapter adapter = new Adapter();
computer.net(adapter);
}
}
//接口转换器的抽象实现
public interface NetToUsb {
//作用:处理请求
public void handleRequest();
}
//真正的适配器 需要连接电脑USB和连接网线
public class Adapter extends WiFi implements NetToUsb{
@Override
public void handleRequest() {
// TODO Auto-generated method stub
super.request();//可以上网了
}
}
对象适配器的实现(组合关系)
基本思路和类的适配器模式相同,只是将Adapter类作修改,不继承WiFi类,而是持有WiFi类的实例。
里氏替换:组合聚合修改继承
//真正的适配器 需要连接电脑USB和连接网线
public class Adapter implements NetToUsb{
private WiFi wifi;
public Adapter() {
super();
}
public Adapter(WiFi wifi) {
super();
this.wifi = wifi;
}
@Override
public void handleRequest() {
// TODO Auto-generated method stub
wifi.request();//可以上网了
}
}
//客户端类:想上网,插不上网线
public class Computer {
public void net(NetToUsb adapter) {
//上网的具体实现,找一个转接头
adapter.handleRequest();
}
public static void main(String[] args) {
Computer computer = new Computer();
WiFi wifi = new WiFi();
Adapter adapter = new Adapter(wifi);
computer.net(adapter);
}
}