适配器模式和代理模式理解

简介: 设计模式简单来说的前人给我们总结的经验,是一系列解决问题的套路。提高我们代码的可读性,复用性,可维护性,扩展性。

设计模式六大原则

  • 单一职责原则: 一个类或者接口只负责唯一项职责,尽量设计出功能单一的接口;
  • 依赖倒转原则: 高层模块不应该依赖底层模块集体实现,即当实现发生变化时,只需提供新的实现类,不需要修改高层的模块代码;
  • **开放-封闭原则:**程序对外扩展开发,对修改关闭,当添加新的需求时,我们提供新的模块类,而不是修改原来的实现的代码。
  • 迪米特法则: 一个对象对其他对象要保持最少的联系,尽量降低类与类之间的耦合度;
  • 里氏代换原则: 所有引用基类(父类)的地方必须能透明地使用其子类的对象;
  • 接口隔离原则: 客户端不应该依赖它不需要的接口,一个类对另一个类的依赖应该建立在最小的接口上;
    带着设计原则再去看设计模式,可能你会说我不使用设计模式我的功能实现的更简单,对的没错。但是你的项目对于最基本的扩展功能基本为零,每一次都是对原来代码的改来改去。

适配器模式

适配器模式是一种结构型模式,在我们生活中有很多例子比如我们出国的话,买一个翻译机,我们说中文,翻译机就会给我们说英文,用户不需要知道翻译机的工作原理。

在我们的开发中可能会遇见系统需要调用支付接口,但是支付接口有很多,比如微信支付,支付宝支付。用户只用选择支付方式就好。调用我们系统的支付接口进行转发,适配器模式重要的就是转换

例子:
模拟支付宝,微信接口

package com.dangle.adapter;
//支付宝
public interface Zhifubao {
	public String zhifubaopay();//模拟支付包支付方法
}

package com.dangle.adapter;
public interface Weixin {
	public String weixinpay();//模拟微信支付方法
}

模拟支付宝,微信实现类

package com.dangle.adapter;
public class ZhifubaoImpl implements Zhifubao{
	@Override
	public String zhifubaopay() {	
		return "支付宝支付成功";
	}
}

package com.dangle.adapter;
public class WeixinImpl implements Weixin{
	@Override
	public String weixinpay() {
		return "微信支付成功";
	}

}

创建支付宝,微信适配器

package com.dangle.adapter;
//支付宝适配器
public class ZhifubaoAdapter implements HopeInterfaces{
	//把真正服务的对象包含进来
	private  Zhifubao zhifubao=new ZhifubaoImpl();
	@Override
	public String payment() {
		loading();
		return zhifubao.zhifubaopay();
	}
	private void loading() {
		System.out.println("支付宝协议通过");
	}
}

package com.dangle.adapter;
public class WeixinAdapter implements HopeInterfaces {
	private  Weixin weixin=new WeixinImpl();
	@Override
	public String payment() {
		System.out.println("微信协议通过");
		String message=weixin.weixinpay();
		return message;
	}
}

客户端

package com.dangle.adapter;
public class client {
	public static void main(String[] args) {
		HopeInterfaces hopeInterfaces=new ZhifubaoAdapter();
		String message=hopeInterfaces.payment();
		System.out.println(message);
		
	}	
}
*支付协议通过
*支付宝支付成功

如果添加了新的支付方式我们直需要添加新的适配器就可以了,这就是设计模式的魅力。

代理模式

代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。通俗的来讲代理模式就是我们生活中常见的中介。

例子:

模拟生产汽车规范类

package com.dangle.agent;
//定义汽车工厂规范接口
public interface Car {
	void productcar(); //生产机车
}

模拟汽车生产商

package com.dangle.agent;
//汽车生厂商
public class CarFactory implements Car{
	@Override
	public void productcar() {
		System.out.println("汽车");	
	}
}

客户端

package com.dangle.agent;
public class Client {
	public static void main(String[] args) {
		Car  car=new CarFactory();
		car.productcar(); 
	}
}
*汽车

当我们想要为奔驰生产上添加售后服务怎么办?修改已经实现的CarFactory的类,可以,但是这就违反了开闭原则,所以就出现了代理模式

创建一个汽车代理商

package com.dangle.agent;
//汽车购买代理商
public class Agent implements Car{
	private CarFactory carFactory;
	@Override
	public void productcar() {
		carFactory.productcar();
		after();
	}
	public CarAgent(CarFactory carFactory) {
		super();
		this.carFactory=carFactory;
		
	}
	private void after() {
		System.out.println("售后服务");
	}
}

客户端

package com.dangle.agent;
//代理模式
public class Client {
	public static void main(String[] args) {
		Car  car=new Agent(new CarFactory());
		car.productcar();
	}
}
*汽车
*售后服务

很明显我们没有修改任何CarFactory类的代码,就实现了业务的增强这就是设计模式的魅力,这属于静态代理,但是当我们不止想代理汽车,如果要代理飞机的话,就要对代理类进行修改要实现,我们就要使用动态代理。

飞机规范接口

package com.dangle.agent;
//飞机接口
public interface Plane {
	void fly();
}

飞机生产商

package com.dangle.agent;
//飞机生产商
public class PlaneFactory implements Plane  {
	@Override
	public void fly() {
		System.out.println("飞机");
	}
}

动态代理类

package com.dangle.agent;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//动态代理
public class DynamicAgent implements InvocationHandler{
	private Object factory;
	
	public DynamicAgent(Object factory) {
		super();
		this.factory=factory;
		// TODO Auto-generated constructor stub
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Object object=method.invoke(factory, args);
		after();
		return object;
	}
	//得到代理类
	public Object getProxyInstance() {
		return Proxy.newProxyInstance(factory.getClass().getClassLoader(), factory.getClass().getInterfaces(), this);
	}
	private void after() {
		System.out.println("售后服务");
	}
}

客户端

package com.dangle.agent;
//代理模式
public class Client {
	public static void main(String[] args) {
		Car car=new CarFactory();
		DynamicAgent dy=new DynamicAgent(car);
		Car a=(Car)dy.getProxyInstance();
		a.productcar();
	}
}
*汽车
*售后服务

升级为动态代理当我们再次有新的服务实现我们就不用在修改代理对象Agent类。mybatis可以实现打印sql日志信息就使用的动态代理,设计模式重在理解和在自己项目的使用。

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×