一、什么是设计模式
设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现在中都有相应的原理来与之对应,每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是它能被广泛应用的原因。简单说:
模式:在某些场景下,针对某类问题的某种通用的解决方案。
场景:项目所在的环境
问题:约束条件,项目目标等
解决方案:通用、可复用的设计,解决约束达到目标。
二、设计模式的三个分类
创建型模式:对象实例化的模式,创建型模式用于解耦对象的实例化过程。
结构型模式:把类或对象结合在一起形成一个更大的结构。
行为型模式:类和对象如何交互,及划分责任和算法。
如下图所示:
创建型:
单例模式:https://blog.csdn.net/Platinum_stars/article/details/108284748
结构型:
代理模式:https://blog.csdn.net/Platinum_stars/article/details/108284483
行为型:
模板模式:https://blog.csdn.net/Platinum_stars/article/details/108284889
代理模式
代理模式:为其他对象提供一个代理以便控制这个对象的访问。
代理模式就是给一个对象提供一个代理,并由代理对象控制对原对象的引用。它使得客户不能直接与真正的目标对象通信。代理对象是目标对象的代表,其他需要与这个目标对象打交道的操作都是和这个代理对象在交涉。
代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了的作用和保护了目标对象的,同时也在一定程度上面减少了系统的耦合度。
代理模式包含如下角色:
- Subject: 抽象主题角色
- Proxy: 代理主题角色
- RealSubject: 真实主题角色
静态代理
/**
* 静态代理举例
* <p>
* 特点:代理类和被代理类在编译期间,就确定下来了。
*
* @author Ankang Huang
* @date 2020/8/27 17:21
*/
public class StaticProxyTest {
public static void main(String[] args) {
// 创建被代理类的对象
NikeClothFactory nikeClothFactory = new NikeClothFactory();
// 创建代理类的对象
ProxyClothFactory proxyClothFactory = new ProxyClothFactory(nikeClothFactory);
proxyClothFactory.produceCloth();
}
}
interface ClothFactory {
void produceCloth();
}
class ProxyClothFactory implements ClothFactory {
private ClothFactory factory;// 用被代理类对象进行实例化
public ProxyClothFactory(ClothFactory factory) {
this.factory = factory;
}
@Override
public void produceCloth() {
System.out.println("代理类准备工作");
factory.produceCloth();
System.out.println("代理类处理收尾");
}
}
class NikeClothFactory implements ClothFactory {
@Override
public void produceCloth() {
System.out.println("Nike工产生产一批鞋子");
}
}
动态代理
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 动态代理
*
* @author Ankang Huang
* @date 2020/8/27 17:28
*/
public class ProxyTest {
public static void main(String[] args) {
SuperMan man = new SuperMan();
//proxyInstance:代理类的对象
Human human = (Human) ProxyFactory.getProxyInstance(man);
//当通过代理类对象调用方法时,会自动的调用被代理类中同名的方法
String belief = human.getBelief();
System.out.println(belief);
human.eat("饭");
System.out.println("************");
NikeClothFactory nikeClothFactory = new NikeClothFactory();
ClothFactory proxyClothFactory = (ClothFactory) ProxyFactory.getProxyInstance(nikeClothFactory);
proxyClothFactory.produceCloth();
}
}
interface Human {
String getBelief();
void eat(String food);
}
/**
* 被代理类
*/
class SuperMan implements Human {
@Override
public String getBelief() {
return "I believe I can fly!";
}
@Override
public void eat(String food) {
System.out.println("我喜欢吃" + food);
}
}
class HuManUtil {
public void method1() {
System.out.println("------通用一------");
}
public void method2() {
System.out.println("------通用二------");
}
}
/**
* 要想实现动态代理,需要解决的问题?
* 问题一:如何根据加载到内存中的被代理类,动态的创建一个代理类及其对象。
* 问题二:当通过代理类的对象调用方法a时,如何动态的去调用被代理类中的同名方法a。
*/
class ProxyFactory {
// 调用此方法,返回一个代理类的对象。解决问题一
public static Object getProxyInstance(Object object) {// object 被代理对象
MyInvocationHandler handler = new MyInvocationHandler();
handler.bind(object);
return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), handler);
}
}
class MyInvocationHandler implements InvocationHandler {
private Object object;// 需要使用被代理类的对象进行赋值
public void bind(Object object) {
this.object = object;
}
// 当我们通过代理类的对象,调用方法a时,就会自动的调用如下的方法:invoke()
// 将被代理类要执行的方法a的功能就声明在invoke()中
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
HuManUtil util = new HuManUtil();
util.method1();
// method:即为代理类对象调用的方法,此方法也就作为了被代理类对象要调用的方法
// obj:被代理类的对象
Object invoke = method.invoke(object, args);
util.method2();
// 上述方法的返回值就作为当前类中的invoke()的返回值。
return invoke;
}
}
本文链接: https://blog.csdn.net/Platinum_stars/article/details/108284483