1.适配器模式
定义:是两个不兼容的接口之间的桥梁,例如读卡器可以让笔记本电脑读取内存卡里的内容,这里的读卡器就是一个桥梁。
代码示例(美国电器电压110V,中国220V,把110V转为220V)
public interface AmericaVoltage {
public String voltage110();
}
public interface ChinaVoltage {
public String voltage220();
}
public class OutputVoltage implements ChinaVoltage{
@Override
public String voltage220() {
return "输出220V电压";
}
}
public class VoltageAdapter implements AmericaVoltage{
private ChinaVoltage chinaVoltage;
public VoltageAdapter(ChinaVoltage chinaVoltage){
this.chinaVoltage = chinaVoltage;
}
@Override
public String voltage110() {
return chinaVoltage.voltage220();
}
}
测试:
public class AdapterTest {
public static void main(String []args){
AmericaVoltage americaVoltage = new VoltageAdapter(new OutputVoltage());
System.out.println(americaVoltage.voltage110());
}
}
结果:
适配器模式不适合在详细设计设计阶段使用,它是一种补偿模式,用于在系统后期的扩展,修改时使用。
过多的使用适配器会让系统非常凌乱,不易整体进行把握。
2.代理模式
定义:为对象提供一种代理来控制对这个对象的访问(目的是控制)。
静态代理:是在程序运行前就存在代理类的字节码文件,代理类和委托类的关系在运行前就已经确定了。
代理对象和真实对象都有一个共同的接口,代理对象中含有对真实对象的引用。
假设我现在有一个类,我想要在这个类中每个public方法真正执行数据库操作前先查询缓存,这时候除了修改原始的类之外的方式就是我可以写个代理类来替代它,这样符合开闭原理。
示例:
public interface UserDao {
public String getUserById(String id);
public void updateUser(String user);
}
public class UserDaoImpl implements UserDao {
UserDaoImpl(){
System.out.println("对象被创建了");
}
@Override
public String getUserById(String id) {
return "用户"+id+"的信息为。。。。。。";
}
@Override
public void updateUser(String user) {
System.out.println("数据库更新用户信息:"+user);
}
}
public class UserDaoImplProxy implements UserDao {
private UserDao userDaoImpl;
@Override
public String getUserById(String id) {
System.out.println("查找之前输出ID:"+id);
if (userDaoImpl == null){
userDaoImpl = new UserDaoImpl();
}
String result = userDaoImpl.getUserById(id);
System.out.println("查找之后输出记录:"+result);
return result;
}
@Override
public void updateUser(String user) {
System.out.println("更新之前输出:"+user);
if (userDaoImpl == null){
userDaoImpl = new UserDaoImpl();
}
userDaoImpl.updateUser(user);
}
}
测试:
public class ProxyTest {
public static void main(String[] args){
UserDao userDaoImplProxy = new UserDaoImplProxy();
userDaoImplProxy.getUserById("1");
userDaoImplProxy.updateUser("{id:1,name:junjun,age:27}");
}
}
结果:
动态代理:是在程序运行期间由JVM根据反射机制动态生成的,不存在代理类的字节码文件,代理角色和真实角色是在程序运行期间确定的(spring的aop)。
示例:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class UserHandler implements InvocationHandler {
private UserDao userDaoImpl;
public UserHandler(UserDao userDaoImpl){
this.userDaoImpl = userDaoImpl;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object object = null;
System.out.println("我要开始调用方法了");
if (method.getName().equals("updateUser")){
object = method.invoke(userDaoImpl,args);
}else {
System.out.println("被拦截了,方法不能执行了:"+method.getName());
}
System.out.println("方法执行结束了");
return object;
}
}
测试:
import java.lang.reflect.Proxy;
public class ProxyTest {
public static void main(String[] args){
UserHandler userHandler = new UserHandler(new UserDaoImpl());
UserDao userProxy = (UserDao) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),new Class[]{UserDao.class},userHandler);
userProxy.updateUser("{id:1,name:junjun,age:27}");
userProxy.getUserById("1");
}
}
结果: