定义:将一个接口转换成客户需要的另一个接口,使得原本因为接口不兼容而不能在一起工作的两个类可以在一起工作。
示意图:
实例1
定义usb接口、ps2接口,模拟适配ps2接口和客户端,客户端需要实现的是usb的功能。
public interface IUsb { //usb接口
void isUsb();
}
public interface IPs2 {//ps2接口
void isPs2();
}
public class Usber implements IUsb {
@Override
public void isUsb() {
// TODO Auto-generated method stub
System.out.println("this is usb!");
}
}
public class Adapter implements IPs2 {//适配器
private IUsb usb;
public Adapter(IUsb usb){
this.usb=usb;
}
@Override
public void isPs2() {
// TODO Auto-generated method stub
usb.isUsb();
}
}
//客户端实现代码
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
IPs2 ips2 = new Adapter(new Usber());
ips2.isPs2();
}
}
实例2
public interface Port {
// 远程SSH端口22
public void SSH();
// 网络端口80
public void NET();
// Tomcat容器端口8080
public void Tomcat();
// Mysql数据库端口3306
public void Mysql();
// Oracle数据库端口1521
public void Oracle();
// 文件传输FTP端口21
public void FTP();
}
/**
* 定义抽象类实现端口接口,但是什么事情都不做
*/
public abstract class Wrapper implements Port{
@Override
public void SSH(){};
@Override
public void NET(){};
@Override
public void Tomcat(){};
@Override
public void Mysql(){};
@Override
public void Oracle(){};
@Override
public void FTP(){};
}
/**
* 提供聊天服务
* 需要网络和文件传输功能
*/
public class Chat extends Wrapper{
@Override
public void NET(){ System.out.println("Hello world!"); };
@Override
public void FTP(){ System.out.println("File upload succeddful!"); };
}
/**
* 网站服务器
* 需要Tomcat容器,Mysql数据库,网络服务,远程服务
*/
public class Server extends Wrapper{
@Override
public void SSH(){ System.out.println("Connect success!"); };
@Override
public void NET(){ System.out.println("Hello WWW!"); };
@Override
public void Tomcat(){ System.out.println("Tomcat 9 is running!"); };
@Override
public void Mysql(){ System.out.println("Mysql is running!"); };
}
/**
* 运行器
* 运行聊天服务和服务器
*/
public class Start {
private static Port chatPort = new Chat();
private static Port serverPort = new Server();
public static void main(String[] args) {
// 聊天服务
chatPort.FTP();
chatPort.NET();
// 服务器
serverPort.Mysql();
serverPort.SSH();
serverPort.Tomcat();
serverPort.NET();
}
}
定义: 桥接模式是指当一个类中存在两种独立变化的维度,通过该模式可以将这两个维度分离出来,使两者独立扩展,让系统更符合单一职责原则。与多重继承方案不同,桥接模式将两个独立变化的维度设计为两个独立的继承等级结构。并且在抽象层建立一个关联,该关联关系类似连接两个独立结构的桥,故名为桥接模式。
桥接模式将类之间静态继承关系转换为动态组合关系,使得系统更加灵活,易于扩展,同时有效的控制了系统中类的个数。
示意图:
实例1:
定义调料抽象类和实现方法:
public abstract class AbstractFlavor {
public abstract void flavor();
}
public class SpicyFlavor extends AbstractFlavor {
@Override
public void flavor() {
// TODO Auto-generated method stub
System.out.println("辣味");
}
}
public class SaltyFlavor extends AbstractFlavor {
@Override
public void flavor() {
// TODO Auto-generated method stub
System.out.println("咸味");
}
}
定义面条抽象类和实现方法:
public abstract class AbstractNoodle {
protected AbstractFlavor flavor;
public AbstractNoodle(AbstractFlavor flavor){
this.flavor=flavor;
}
public abstract void noodle();
}
public class BeefNoodle extends AbstractNoodle {
public BeefNoodle(AbstractFlavor flavor){
super(flavor);
}
@Override
public void noodle() {
// TODO Auto-generated method stub
System.out.print("这是牛肉面条,味道是");
super.flavor.flavor();
}
}
public class SheetNoodle extends AbstractNoodle {
public SheetNoodle(AbstractFlavor flavor){
super(flavor);
}
@Override
public void noodle() {
// TODO Auto-generated method stub
System.out.print("这是羊肉面,味道是");
super.flavor.flavor();
}
}
测试:
public class Test {
public static void main(String[] args) {
//定义调料味道
AbstractFlavor spicyFlavor = new SpicyFlavor();
AbstractFlavor saltyFlavor = new SaltyFlavor();
//定义面条
AbstractNoodle beefNoodle1 = new BeefNoodle(spicyFlavor);
AbstractNoodle beefNoodle2 = new BeefNoodle(saltyFlavor);
AbstractNoodle sheetNoodle1 = new SheetNoodle(spicyFlavor);
AbstractNoodle sheetNoodle2 = new SheetNoodle(saltyFlavor);
beefNoodle1.noodle();
beefNoodle2.noodle();
sheetNoodle1.noodle();
sheetNoodle2.noodle();
}
}
实例2:
假设有报表数据展示和数据采集两个模块,其中数据采集的方式有多种包含配置文件读取、xml读取、数据库读取等。现在结合适配器和桥接模式设计实例。
定义数据采集接口和数据展示抽象类。
public interface IDataCollect {
public List
}
public abstract class AbstractDataShow {
protected DataCollectAdapter collect;
public AbstractDataShow(DataCollectAdapter collect){
this.collect=collect;
}
public abstract void dataShow();
}
定义以及数据采集对应的适配器类。
public class DataCollectAdapter{
private IDataCollect collect;
public void setCollect(IDataCollect collect) {
this.collect = collect;
}
public String collectData() {
// TODO Auto-generated method stub
String string = "";
List
for(String str:list){
string+=str;
}
return string;
}
}
定义数据采集接口各实现类
public class DataCollectXml implements IDataCollect {
private SAXReader saxReader = null;
private InputStream inputStream = null;
private Document document = null;
private String name = null;
private String dec = null;
private DataCollectXml(){
saxReader = new SAXReader();
try {
inputStream = DataCollectXml.class.getClassLoader().
getResourceAsStream("xml/dataCollect.xml");
document = saxReader.read(inputStream);
Element element = document.getRootElement();
Element element1 = element.element("name");
Element element2 = element.element("dec");
name = element1.getText();
dec = element2.getText();
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static class InnerClass{
private final static DataCollectXml INSTANCE = new DataCollectXml();
}
public static DataCollectXml getInstance(){
return InnerClass.INSTANCE;
}
@Override
public List
// TODO Auto-generated method stub
List
list.add(name);
list.add(dec);
return list;
}
}
public class DataCollectDB implements IDataCollect {
@Override
public List
// TODO Auto-generated method stub
List
list.add("name");
list.add("dec");
return list;
}
}
public class DataCollectConfig implements IDataCollect {
private Properties properties = null;
private InputStream inputStream = null;
private String name = null;
private String dec = null;
private DataCollectConfig(){
try {
properties = new Properties();
inputStream = DataCollectConfig.class.getClassLoader().
getResourceAsStream("properties/dataCollect.properties");
properties.load(inputStream);
name = properties.getProperty("name");
dec = properties.getProperty("dec");
} catch (Exception e) {
// TODO: handle exception
System.out.println("加载配置文件有误!");
}finally{
properties.clear();
try {
inputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private static class InnerClass{
private static final DataCollectConfig INSTANCE = new DataCollectConfig();
}
public static DataCollectConfig getInstance(){
return InnerClass.INSTANCE;
}
@Override
public List
// TODO Auto-generated method stub
List
list.add(name);
list.add(dec);
return list;
}
}
定义数据展示类。
public class BrowserShow extends AbstractDataShow {
public BrowserShow(DataCollectAdapter collect) {
super(collect);
// TODO Auto-generated constructor stub
}
@Override
public void dataShow() {
// TODO Auto-generated method stub
String str = collect.collectData();
System.out.println(str);
}
}
定义测试类。
public class Test {
public static void main(String[] args) {
IDataCollect collect1 =DataCollectXml.getInstance();
IDataCollect collect2 =DataCollectConfig.getInstance();
IDataCollect collect3 =new DataCollectDB();
List
list.add(collect1);
list.add(collect2);
list.add(collect3);
DataCollectAdapter adapter = new DataCollectAdapter();
for(IDataCollect collect:list){
adapter.setCollect(collect);
System.out.println(adapter.collectData());
}
}
}
定义:为其他对象提供一种代理以控制对这个对象的控制。
示意图:
分类:
远程代理:为一个存在于不同地址空间的对象提供远程代理,这样就可以隐藏对象存在于不同地址空间的事实。
虚拟代理:是根据需要创建开销很大的对象,通过他来存放实例化需要很长时间的对象。
安全代理:用来控制需要访问真是对象的权限。
只能指引:是指通过代理对象时,只能处理其他一些事。
静态代理实例:
静态代理类接口
public interface IStaticProxyInterface {
public void proxyRun();
}
静态代理实现类
public class StaticProxyImpl implements IStaticProxyInterface {
@Override
public void proxyRun() {
System.out.println("this is staticProxyImpl!");
}
}
静态代理类
public class StaticProxy implements IStaticProxyInterface {
private IStaticProxyInterface staticProxy;
public StaticProxy(IStaticProxyInterface staticProxy){
this.staticProxy=staticProxy;
}
@Override
public void proxyRun() {
// TODO Auto-generated method stub
System.out.println("静态代理事物开始.......");
staticProxy.proxyRun();
System.out.println("静态事物结束..........");
}
}
测试类
public class Test {
public static void main(String[] args) {
IStaticProxyInterface proxyImpl = new StaticProxyImpl();
IStaticProxyInterface proxy = new StaticProxy(proxyImpl);
proxy.proxyRun();
}
}
JDK动态代理实例:
动态代理接口
public interface IJDKProxyInterface {
public void proxyRun();
}
动态代理实现类
public class JDKProxyImpl implements IJDKProxyInterface {
@Override
public void proxyRun() {
System.out.println("this is JDKProxyImpl!");
}
}
动态代理类
public class JDKProxy implements InvocationHandler{
private Object target_interface_implements;
public Object dynamicBindImplToProxyClass(Object target_interface_implements) {
// TODO Auto-generated method stub
this.target_interface_implements = target_interface_implements;
return Proxy.newProxyInstance(target_interface_implements.getClass().getClassLoader(),
target_interface_implements.getClass().getInterfaces(),this);
}
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
System.out.println("事物处理之前......");
Object returnOBJ = method.invoke(target_interface_implements, args);
System.out.println("事物处理之后......");
return returnOBJ;
}
}
测试类
public class Test {
public static void main(String[] args) {
JDKProxy proxy = new JDKProxy();
IJDKProxyInterface jdkproxy = (IJDKProxyInterface)proxy.
dynamicBindImplToProxyClass(new JDKProxyImpl());
jdkproxy.proxyRun();
}
}
CGLIB动态代理实例:
动态代理实现类
public class CglibProxyImpl {
public void cglibRun(){
System.out.println("cglib动态代理实现类,开始运行....");
}
}
Cglib动态代理类
public class CglibProxy implements MethodInterceptor {
private Object target_class;
public Object getInstance(Object target_class){
this.target_class=target_class;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.target_class.getClass());
//回調方法
enhancer.setCallback(this);
//創建代理對象
return enhancer.create();
}
@Override
public Object intercept(Object arg0, Method arg1, Object[] arg2,
MethodProxy arg3) throws Throwable {
// TODO Auto-generated method stub
System.out.println("處理代理對象之前......");
arg3.invokeSuper(arg0, arg2);
System.out.println("处理代理对象之后......");
return null;
}
}
测试类
public class Test {
public static void main(String[] args) {
CglibProxy cglibProxy = new CglibProxy();
CglibProxyImpl cglibProxyImpl = (CglibProxyImpl)cglibProxy.getInstance(new CglibProxyImpl());
cglibProxyImpl.cglibRun();
}
}
适配器模式和代理模式的区别:
适配器模式是因为新旧接口不一致导致出现了客户端无法得到满足的问题,但是,由于旧的接口是不能被完全重构掉的,因为我们还想使用实现了这个接口的一些服务。那么为了使用以前实现旧接口的服务,我们就应该把新的接口转换成旧接口;实现这个转换的类就是抽象意义的转换器;(应用于特定的场景,新旧对接接口都不方便改造时使用)
代理模式,都是继承相同的接口,为了屏蔽对原来对象的访问,并可以在访问代理对象的时候进行处理。