设计模式
1、简介
设计模式(Design Pattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路。它不是语法规定,而是一套用来提高代码可复用性、可维护性、可读性、稳健性以及安全性的解决方案。
1995 年,GoF(Gang of Four,四人组/四人帮)合作出版了《设计模式:可复用面向对象软件的基础》一书,共收录了 23 种设计模式,从此树立了软件设计模式领域的里程碑,人称「GoF设计模式」。
2、分类
创建型模式
描述怎样去创建一个对象
工厂模式、抽象工厂模式、单例模式、建造者模式、原型模式
结构型模式
描述类或对象如何按照某种布局组成更大的结构
适配器模式、装饰器模式、代理模式、外观模式桥接模式、组合模式、享元模式
行为型模式
描述类或对象之间如何互相协作完成单个对象无法完成的任务
策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模备忘录模式、状态模式、访问者模式、中介者模式、解释器模式
OOP七大原则
1、开闭原则
对扩展开放,对修改关闭。当需求发生改变的时候,不要修改原来的代码,而是对其经行扩展。
2、里氏替换原则
继承必须确保父类所拥有的性质在子类中依然成立。
3、依赖倒置原则
面向接口编程,不要面向实现编程。
4、单一职责原则
控制类的粒度大小,将对象解耦,提高内聚性。一个类只需干好一件事,不要做太多事。
5、接口隔离原则
要为各个类建立它们的专用接口。
6、迪米特原则
只与你的直接朋友交谈,不要跟陌生人说话。
7、合成复用原则
尽量先使用组合或者聚合等关联关系来实现,其次才考虑继承关系。
代理模式
静态代理
角色分析:
- 抽象角色:代理对象和真实角色共同要完成的事情,一般使用接口或抽象类。
- 真实角色:被代理的角色
- 代理角色:代理真实角色,一般会有附属操作
- 客户:访问代理对象的人
优点:
- 真实角色不用去关注一些公共业务
- 公共业务交给代理角色,实现业务分工
- 公共业务发生扩展时,可集中管理
缺点:
- 一个真实角色会生成一个代理角色,代码量翻倍
/**
* @author xy
* @date 2020/5/26
* 抽象角色
*/
public interface IUserService {
void add();
}
/**
* @author xy
* @date 2020/5/26
* 真实角色
* 代理角色要与真实角色有相同的需求
*/
public class UserServiceImpl implements IUserService {
@Override
public void add() {
System.out.println("增加用户");
}
}
/**
* @author xy
* @date 2020/5/26
* 客户
*/
public class Client {
public static void main(String[] args) {
UserServiceImpl userService = new UserServiceImpl();
//使用方法时要打印一个日志,最好不要改变原有代码,找代理来实现方法最好
Proxy proxy = new Proxy();
proxy.setUserService(userService);
proxy.delete();
}
}
/**
* @author xy
* @date 2020/5/26
* 代理角色
* 代理角色要与真实角色有相同的需求
*/
public class Proxy implements IUserService {
//代理真实对象
private UserServiceImpl userService;
public void setUserService(UserServiceImpl userService) {
this.userService = userService;
}
@Override
public void add() {
log("add");
userService.add();
}
//添加日志的方法
public void log(String msg){
System.out.println("使用了"+msg+"方法");
}
}
动态代理
- 动态代理类是动态生成的
- 分两大类,基于接口(JDK)和基于类(cglib)
- InvocationHandler调用处理程序返回执行结果,Proxy动态生成代理
- 一个动态代理类代理的是一个接口,可以代理多个类
/**
* @author xy
* @date 2020/5/26
* 要用这个类自动生成代理类
*/
public class ProxyInvocationHandler implements InvocationHandler {
//定义被代理的接口
private Object target;
public void setTarget(Object target) {
this.target = target;
}
//得到代理对象
public Object getProxy() {
//当前类加载器,代理类的接口,当前InvocationHandler
return Proxy.newProxyInstance(this.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
}
//处理代理实例并返回结果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//反射实现
log(method.getName());
return method.invoke(target, args);
}
private void log(String msg){
System.out.print("调用了" + msg +"方法,");
}
}
/**
* @author xy
* @date 2020/5/26
* 客户
*/
public class Client {
public static void main(String[] args) {
//获取真实角色
UserServiceImpl userService = new UserServiceImpl();
ProxyInvocationHandler handler = new ProxyInvocationHandler();
//设置代理接口
handler.setTarget(userService);
//获取代理角色
IUserService proxy = (IUserService) handler.getProxy();
proxy.find();
proxy.update();
}
}
/**
* @author xy
* @date 2020/5/26
*/
public class Agent implements InvocationHandler {
//直接传入抽象角色
public static <T> T getProxy(Class<T> clazz) {
Agent agent = new Agent();
//当前类加载器,代理类的接口,当前InvocationHandler
return (T)Proxy.newProxyInstance(Agent.class.getClassLoader(),new Class[] {clazz}, agent);
}
//处理代理实例并返回结果
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
log(method.getName());
return null;
}
private void log(String msg){
System.out.println("调用了" + msg +"方法");
}
}