JAVA设计模式
序言
本文章参考与大话设计模式这本书
1.简单工厂模式
- 定义
客户只需要告诉工厂,我的需求是什么,然后工厂来满足需求。
客户并不知道工厂如何操作,只关系结果 - 场景
实现计算机器功能,加减法 - 代码示例
/**
* @author GuoZhong
* @description 操作类父类
* @date 2023/2/12 23:13
*/
public class Operate {
public int twoOperate(int numOne, int numTwo){
int result=0;
return result;
}
}
/**
* @author GuoZhong
* @description 加法
* @date 2023/2/12 23:15
*/
public class AddOperate extends Operate {
@Override
public int twoOperate(int numOne, int numTwo){
return numOne+numTwo;
}
}
/**
* @author GuoZhong
* @description 减法
* @date 2023/2/12 23:22
*/
public class SubOperate extends Operate {
@Override
public int twoOperate(int numOne, int numTwo) {
return numOne-numTwo;
}
}
/**
* @author GuoZhong
* @description 工厂
* @date 2023/2/12 23:12
*/
public class SimpleFactory {
public Operate createOperateInstance(String operateType){
Operate operate=null;
switch (operateType){
case "+":
operate=new AddOperate();
break;
case "-":
operate=new SubOperate();
break;
}
return operate;
}
}
/**
* @author GuoZhong
* @description 测试
* @date 2023/2/12 23:28
*/
public class Test {
public static void main(String[] args) {
SimpleFactory simpleFactory=new SimpleFactory();
Operate operateInstance = simpleFactory.createOperateInstance("+");
int i = operateInstance.twoOperate(1, 2);
System.out.println(i);
}
}
2.策略模式
- 定义
客户去商场买蛋糕,可以选择自己去做,用商家的原材料,也可以选择让商家去做 - 场景
商场促销 - 代码示例
/**
* @Author: GZ
* @CreateTime: 2023-02-14 11:26
* @Description: 抽象算法类
* @Version: 1.0
*/
public abstract class Strategy {
/**
* 操作抽象方法
*/
public abstract void operation();
}
/**
* @Author: GZ
* @CreateTime: 2023-02-14 11:28
* @Description: 具体算法A
* @Version: 1.0
*/
public class ConcreteStrategyA extends Strategy{
@Override
public void operation() {
System.out.println("算法A");
}
}
/**
* @Author: GZ
* @CreateTime: 2023-02-14 11:29
* @Description: TODO
* @Version: 1.0
*/
public class ConcreteStrategyB extends Strategy {
@Override
public void operation() {
System.out.println("算法B");
}
}
public class Context {
Strategy strategy;
public Context( Strategy strategy){
this.strategy = strategy;
}
public void ContextOperate(){
strategy.operation();
}
}
public class ClientDemo {
public static void main(String[] args) {
Context context;
context=new Context(new ConcreteStrategyA());
context.ContextOperate();
context=new Context(new ConcreteStrategyB());
context.ContextOperate();
}
}
- 思考
你会发现如何去选择自己需要算法,还是在客户端实现的,这时你可以结合把策略模式与工厂模式进行结合使用
3.装饰者模式
- 定义
动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活 - 场景
约会时穿衣打扮 - 代码示例
/**
* @Author: GZ
* @CreateTime: 2023-02-15 14:53
* @Description: 抽象类
* @Version: 1.0
*/
public abstract class Component {
/**
* 抽象方法
*/
public abstract void operation();
}
/**
* @Author: GZ
* @CreateTime: 2023-02-15 14:55
* @Description: 具体对象
* @Version: 1.0
*/
public class ConcreteComponent extends Component{
@Override
public void operation() {
System.out.println("具体对象的操作");
}
}
*/
public abstract class Decorator extends Component {
protected Component component;
public void setComponent(Component component){
this.component = component;
}
@Override
public void operation() {
if (component!=null) {
component.operation();
}
}
}
**
* @Author: GZ
* @CreateTime: 2023-02-15 15:01
* @Description: TODO
* @Version: 1.0
*/
public class ConcreteDecoratorA extends Decorator{
private String addedState;
@Override
public void operation() {
super.operation();
addedState="new state";
System.out.println("具体装饰对象A的操作");
}
}
/**
* @Author: GZ
* @CreateTime: 2023-02-15 15:03
* @Description: TODO
* @Version: 1.0
*/
public class ConcreteDecoratorB extends Decorator{
@Override
public void operation() {
super.operation();
addedBehavior();
System.out.println("具体装饰对象B的操作");
}
private void addedBehavior() {
System.out.println("具体装饰对象B的行为操作");
}
}
/**
* @Author: GZ
* @CreateTime: 2023-02-15 15:05
* @Description: 装饰者客户端
* @Version: 1.0
*/
public class DecoratorClient {
public static void main(String[] args) {
ConcreteComponent c=new ConcreteComponent();
ConcreteDecoratorA a=new ConcreteDecoratorA();
ConcreteDecoratorB b = new ConcreteDecoratorB();
a.setComponent(c);
b.setComponent(a);
System.out.println();
b.operation();
}
4.代理模式
- 定义
代理别人工作 - 场景
追求者与被追求者 - 代码示例
/**
* @Author: GZ
* @CreateTime: 2023-02-16 13:15
* @Description: 被追求者
* @Version: 1.0
*/
@Data
public class SchoolGirl {
public String name;
}
/**
* @Author: GZ
* @CreateTime: 2023-02-16 13:14
* @Description: 追求者
* @Version: 1.0
*/
public class Pursuit {
SchoolGirl mm;
public Pursuit(SchoolGirl mm) {
this.mm = mm;
}
public void sendGive(){
System.out.println("送你礼物"+mm.getName());
}
}
/**
* @Author: GZ
* @CreateTime: 2023-02-16 13:21
* @Description: 代理类
* @Version: 1.0
*/
public class Proxy {
Pursuit pursuit;
public Proxy( SchoolGirl schoolGirl){
pursuit = new Pursuit(schoolGirl);
}
public void proxySendGive(){
pursuit.sendGive();
}
}
* @Author: GZ
* @CreateTime: 2023-02-16 13:17
* @Description: 代理模式演示代码
* @Version: 1.0
*/
public class ClientDemo {
public static void main(String[] args) {
SchoolGirl schoolGirl=new SchoolGirl();
schoolGirl.setName("小姐姐");
Proxy proxy = new Proxy(schoolGirl);
proxy.proxySendGive();
}
}
5.工厂模式
- 定义
为了解决简单工厂问题,开放封闭原则 - 场景
计算器 - 代码示例
public abstract class Operate {
public abstract int getResult(int a,int b);
}
public class OperateAdd extends Operate{
@Override
public int getResult(int a,int b){
return a+b;
}
}
public interface Factory {
public Operate createOperate();
}
public class AddFactory implements Factory{
@Override
public Operate createOperate() {
return new OperateAdd();
}
}
public class ClientDemo {
public static void main(String[] args) {
Factory factory = new AddFactory();
Operate operate = factory.createOperate();
int result = operate.getResult(1, 2);
System.out.println(result);
}
}
6.原型模式
原文连接:https://blog.youkuaiyun.com/m0_47944994/article/details/127884565
- 定义
用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型对象相同的新对象。 - 类型
1.浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。
2.深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。 - 代码示例
–浅克隆
package com.insound.commontest.util.prototype;
/**
* @Author: GZ
* @CreateTime: 2023-02-17 09:57
* @Description: TODO
* @Version: 1.0
*/
//具体原型类
public class Sheep implements Cloneable {
private String name;
private int age;
private String color;
private String address = "蒙古羊";
public Sheep friend; //是对象, 克隆是会如何处理
public Sheep(String name, int age, String color) {
super();
this.name = name;
this.age = age;
this.color = color;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
@Override
public String toString() {
return "Sheep [name=" + name + ", age=" + age + ", color=" + color + ", address=" + address + "]";
}
//克隆该实例
//重写clone方法,或者用默认的clone方法也行,只不过调用时候需要抛异常
@Override
protected Object clone() {
Sheep sheep = null;
try {
sheep = (Sheep)super.clone();
} catch (Exception e) {
System.out.println(e.getMessage());
}
return sheep;
}
}
*/
public class ClientDemo {
public static void main(String[] args) {
Sheep sheep = new Sheep("tom", 1, "白色");
sheep.friend = new Sheep("jack", 2, "黑色");
//克隆
Sheep sheep2 = (Sheep)sheep.clone();
Sheep sheep3 = (Sheep)sheep.clone();
Sheep sheep4 = (Sheep)sheep.clone();
Sheep sheep5 = (Sheep)sheep.clone();
System.out.println("sheep2 =" + sheep2 + "sheep2.friend=" + sheep2.friend.hashCode());
System.out.println("sheep3 =" + sheep3 + "sheep3.friend=" + sheep3.friend.hashCode());
System.out.println("sheep4 =" + sheep4 + "sheep4.friend=" + sheep4.friend.hashCode());
System.out.println("sheep5 =" + sheep5 + "sheep5.friend=" + sheep5.friend.hashCode());
}
}
–深拷贝
package com.insound.commontest.util.prototype;
import java.io.Serializable;
/**
* @Author: GZ
* @CreateTime: 2023-02-17 10:22
* @Description: 引用类型
* @Version: 1.0
*/
public class DeepCloneableTarget implements Serializable,Cloneable {
private static final long serialVersionUID = 1L;
private String cloneName;
private String cloneClass;
/**
* 构造器
* @param cloneName
* @param cloneClass
*/
public DeepCloneableTarget(String cloneName, String cloneClass) {
this.cloneName = cloneName;
this.cloneClass = cloneClass;
}
/**
* 因为该类的属性,都是String , 因此我们这里使用默认的clone完成即可
* @return
* @throws CloneNotSupportedException
*/
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
package com.insound.commontest.util.prototype;
import java.io.*;
/**
* @Author: GZ
* @CreateTime: 2023-02-17 10:26
* @Description: TODO
* @Version: 1.0
*/
public class DeepProtoType implements Serializable, Cloneable {
public String name;
public DeepCloneableTarget deepCloneableTarget;
public DeepProtoType() {
super();
}
// 1 使用clone 方法
@Override
protected Object clone() throws CloneNotSupportedException {
Object deep = null;
//这里完成对基本数据类型(属性)和String的克隆
deep = super.clone();
//克隆引用类型,对引用类型的属性,进行单独处理
DeepProtoType deepProtoType = (DeepProtoType) deep;
deepProtoType.deepCloneableTarget = (DeepCloneableTarget) deepCloneableTarget.clone();
return deepProtoType;
}
//深拷贝 - 方式2 通过对象的序列化实现 (推荐)
public Object deepClone() {
//创建流对象
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
ByteArrayInputStream bis = null;
ObjectInputStream ois = null;
try {
//序列化
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
//当前这个对象以对象流的方式输出
oos.writeObject(this);
//反序列化
bis = new ByteArrayInputStream(bos.toByteArray());
ois = new ObjectInputStream(bis);
DeepProtoType copyObj = (DeepProtoType) ois.readObject();
return copyObj;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
//关闭流
try {
bos.close();
oos.close();
bis.close();
ois.close();
} catch (Exception e2) {
System.out.println(e2.getMessage());
}
}
}
}
package com.insound.commontest.util.prototype;
/**
* @Author: GZ
* @CreateTime: 2023-02-17 09:09
* @Description: 客户端测试
* @Version: 1.0
*/
public class ClientDemo {
public static void main(String[] args) {
/* Sheep sheep = new Sheep("tom", 1, "白色");
sheep.friend = new Sheep("jack", 2, "黑色");
//克隆
Sheep sheep2 = (Sheep)sheep.clone();
Sheep sheep3 = (Sheep)sheep.clone();
Sheep sheep4 = (Sheep)sheep.clone();
Sheep sheep5 = (Sheep)sheep.clone();
System.out.println("sheep2 =" + sheep2 + "sheep2.friend=" + sheep2.friend.hashCode());
System.out.println("sheep3 =" + sheep3 + "sheep3.friend=" + sheep3.friend.hashCode());
System.out.println("sheep4 =" + sheep4 + "sheep4.friend=" + sheep4.friend.hashCode());
System.out.println("sheep5 =" + sheep5 + "sheep5.friend=" + sheep5.friend.hashCode());*/
DeepProtoType p = new DeepProtoType();
p.name = "宋江";
p.deepCloneableTarget = new DeepCloneableTarget("大牛", "小牛");
//方式2 完成深拷贝
DeepProtoType p2 = (DeepProtoType) p.deepClone();
System.out.println("p.name=" + p.name + "p.deepCloneableTarget=" + p.deepCloneableTarget.hashCode());
System.out.println("p2.name=" + p.name + "p2.deepCloneableTarget=" + p2.deepCloneableTarget.hashCode());
}
}
7.模板模式
- 定义
父类中定义好一个操作的框架(方法),在框架中一个步骤就是一个抽象方法,具体的步骤交给子类来实现,而每个子类的实现的细节都不一致。已达到不同的子类完成一个相似的操作而细节都不一致。 - 代码示例
package com.insound.commontest.util.Template;
/**
* @Author: GZ
* @CreateTime: 2023-02-20 09:57
* @Description: 父类试卷
* @Version: 1.0
*/
public abstract class TestPaper {
public void testQuestion1(){
System.out.println("考试试卷1");
answer1();
}
/**
* 答案
*/
public abstract void answer1() ;
public void testQuestion2(){
System.out.println("考试试卷2");
answer2();
}
/**
* 答案
*/
public abstract void answer2() ;
}
package com.insound.commontest.util.Template;
/**
* @Author: GZ
* @CreateTime: 2023-02-20 09:59
* @Description: TODO
* @Version: 1.0
*/
public class TestPaperA extends TestPaper{
@Override
public void answer1() {
System.out.println("A1");
}
@Override
public void answer2() {
System.out.println("A2");
}
}
package com.insound.commontest.util.Template;
/**
* @Author: GZ
* @CreateTime: 2023-02-20 10:00
* @Description: TODO
* @Version: 1.0
*/
public class TestPaperB extends TestPaper{
@Override
public void answer1() {
System.out.println("B1");
}
@Override
public void answer2() {
System.out.println("B2");
}
}
package com.insound.commontest.util.Template;
/**
* @Author: GZ
* @CreateTime: 2023-02-20 10:15
* @Description: TODO
* @Version: 1.0
*/
public class ClientDemo {
public static void main(String[] args) {
TestPaper testPaperA=new TestPaperA();
testPaperA.testQuestion1();
testPaperA.testQuestion2();
}
}
8.外观模式
- 定义
为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用 - 代码示例
package com.insound.commontest.util.appearance;
/**
* @Author: GZ
* @CreateTime: 2023-02-20 11:57
* @Description: 基金
* @Version: 1.0
*/
public class Fund {
Stock1 gu1;
public Fund() {
gu1=new Stock1();
}
public void buyFund(){
gu1.buy();
}
public void sellFund() {
gu1.sell();
}
}
package com.insound.commontest.util.appearance;
/**
* @Author: GZ
* @CreateTime: 2023-02-20 11:55
* @Description: TODO
* @Version: 1.0
*/
public class Stock1 {
public void sell(){
System.out.println("股票买出");
}
public void buy(){
System.out.println("股票买入");
}
}
package com.insound.commontest.util.appearance;
/**
* @Author: GZ
* @CreateTime: 2023-02-20 11:57
* @Description: TODO
* @Version: 1.0
*/
public class ClientDemo {
public static void main(String[] args) {
Fund fd=new Fund();
fd.buyFund();
fd.sellFund();
}
}
9.建造者模式
- 定义
将一个 复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示 - 代码示例
package com.insound.commontest.util.build;
import java.awt.*;
/**
* @Author: GZ
* @CreateTime: 2023-02-20 13:20
* @Description: TODO
* @Version: 1.0
*/
public abstract class PersonBuilder {
public Graphics g;
public Pen p;
public PersonBuilder(Graphics g,Pen p) {
this.g = g;
this.p = p;
}
public abstract void builderHead();
public abstract void builderBody();
public abstract void builderArmLeft();
public abstract void builderArmRight();
public abstract void builderLegLeft();
public abstract void builderLegRight();
}
package com.insound.commontest.util.build;
/**
* @Author: GZ
* @CreateTime: 2023-02-20 13:28
* @Description: TODO
* @Version: 1.0
*/
public class PersonDirector {
private PersonBuilder pb;
public PersonDirector(PersonBuilder pb){
this.pb = pb;
}
public void createPerson(){
pb.builderLegLeft();
pb.builderHead();
pb.builderBody();
pb.builderLegRight();
}
}
package com.insound.commontest.util.build;
import java.awt.*;
/**
* @Author: GZ
* @CreateTime: 2023-02-20 13:24
* @Description: TODO
* @Version: 1.0
*/
public class PersonThinBuilder extends PersonBuilder{
public PersonThinBuilder(Graphics g, Pen p) {
super(g, p);
}
@Override
public void builderHead() {
g.drawRect(1,2,5,6);
}
@Override
public void builderBody() {
g.drawRect(1,2,5,6);
}
@Override
public void builderArmLeft() {
g.drawRect(1,2,5,6);
}
@Override
public void builderArmRight() {
g.drawRect(1,2,5,6);
}
@Override
public void builderLegLeft() {
g.drawRect(1,2,5,6);
}
@Override
public void builderLegRight() {
g.drawRect(1,2,5,6);
}
}
package com.insound.commontest.util.build;
/**
* @Author: GZ
* @CreateTime: 2023-02-20 13:21
* @Description: TODO
* @Version: 1.0
*/
public class Pen {
}
package com.insound.commontest.util.build;
import java.awt.*;
/**
* @Author: GZ
* @CreateTime: 2023-02-20 13:14
* @Description: 建造者模式
* @Version: 1.0
*/
public class ClientDemo {
public static void main(String[] args) {
Pen p=new Pen();
Graphics g=null;
PersonThinBuilder ptb=new PersonThinBuilder(g,p);
PersonDirector pdThin=new PersonDirector(ptb);
pdThin.createPerson();
}
}
10.抽象工厂模式
- 定义
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类 - 图例
- 思考
无论用什么工厂方式,总是要修改,是否需要反射加抽象工程解决
11.单例模式
- 代码示例
– 饿汉模式
/**
*/
public class Singleton {
/**
* 私有实例,静态变量会在类加载的时候初始化,是线程安全的
*/
private static final Singleton instance = new Singleton();
/**
* 私有构造方法
*/
private Singleton() {
}
/**
* 唯一公开获取实例的方法(静态工厂方法)
*
* @return
*/
public static Singleton getInstance() {
return instance;
}
}
– 懒汉模式
/**
* @author lucia
* @date 2022/6/23 13:52
*/
public class Singleton {
/**
* 私有实例 volatile
*/
private volatile static Singleton instance;
/**
* 私有构造方法
*/
private Singleton() {
}
/**
* 唯一公开获取实例的方法(静态工厂方法)
*
* @return
*/
public static Singleton getUniqueInstance() {
//第一个 if 语句用来避免 uniqueInstance 已经被实例化之后的加锁操作
if (instance == null) {
// 加锁
synchronized (Singleton.class) {
//第二个 if 语句进行了加锁,所以只能有一个线程进入,就不会出现 instance == null 时两个线程同时进行实例化操作。
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
12.享元模式
- 定义
“享” 是共享的意思,“元” 是对象的意思 - 场景
数据库缓存池以及Integer - 示例
可以看一下Integer 源码,就是用的享元模式
先去缓存里面拿,没有再去创建
13.责任链模式
- 定义
就是将链中的每一个结点看做是一个对象,每个结点处理请求均不同,且内部自动维护一个下一个结点对象。当请求从链条的首端出发时,会沿着链的路径依次传递给每一个结点的对象,直到有对象处理这个请求为止
- 代码案例
package com.insound.commontest.util.chain;
/**
* @Author: GZ
* @CreateTime: 2023-02-21 15:27
* @Description: TODO
* @Version: 1.0
*/
public abstract class Approve {
Approve approve;
String name ;
public Approve(String name){
this.name = name;
}
public void setApprove(Approve approve) {
this.approve = approve;
}
/**
*
* @param approveRequest
*/
public abstract void processApprove(ApproveRequest approveRequest);
}
package com.insound.commontest.util.chain;
/**
* @Author: GZ
* @CreateTime: 2023-02-21 15:26
* @Description: TODO
* @Version: 1.0
*/
public class ApproveRequest {
private int type = 0;
private float price = 0.0f;
private int id = 0;
//构造器
public ApproveRequest(int type, float price, int id) {
this.type = type;
this.price = price;
this.id = id;
}
public int getType() { return type; }
public float getPrice() { return price; }
public int getId() { return id; }
}
package com.insound.commontest.util.chain;
/**
* @Author: GZ
* @CreateTime: 2023-02-21 15:33
* @Description: TODO
* @Version: 1.0
*/
public class CollegeApprove extends Approve{
public CollegeApprove(String name) {
super(name);
}
@Override
public void processApprove(ApproveRequest approveRequest) {
/* if(approveRequest.getPrice() < 5000 && approveRequest.getPrice() <= 10000) {*/
System.out.println(" 请求编号 id= " + approveRequest.getId() + " 被 " + this.name + " 处理");
/*}else {
approve.processApprove(approveRequest);*/
/* }*/
}
}
package com.insound.commontest.util.chain;
/**
* @Author: GZ
* @CreateTime: 2023-02-21 15:29
* @Description: TODO
* @Version: 1.0
*/
public class DepartmentApprove extends Approve {
public DepartmentApprove(String name) {
super(name);
}
@Override
public void processApprove(ApproveRequest approveRequest) {
if(approveRequest.getPrice() <= 5000) {
System.out.println(" 请求编号 id= " + approveRequest.getId() + " 被 " + this.name + " 处理");
}else {
approve.processApprove(approveRequest);
}
}
}
package com.insound.commontest.util.chain;
/**
* @Author: GZ
* @CreateTime: 2023-02-21 15:35
* @Description: TODO
* @Version: 1.0
*/
public class ClientDemo {
public static void main(String[] args) {
//创建一个请求
ApproveRequest approveRequest = new ApproveRequest(1, 31000, 1);
//创建相关的审批人
DepartmentApprove departmentApprove = new DepartmentApprove("张主任");
CollegeApprove collegeApprove = new CollegeApprove("李院长");
//需要将各个审批级别的下一个设置好
departmentApprove.setApprove(collegeApprove);
//单向责任链这里可以不加
departmentApprove.processApprove(approveRequest);
}
}
14.适配器模式
- 将一个类的接口转换成客户希望的另外一个接口,apdater模式使得原本由于接口不兼容而不能一起工作的哪些类可以一起工作
- 代码案例
/**
* @Author: GZ
* @CreateTime: 2023-02-21 15:45
* @Description: TODO
* @Version: 1.0
*/
public class Adaptee {
public void specificRes(){
System.out.println("特殊请求");
}
}
package com.insound.commontest.util.adaptee;
/**
* @Author: GZ
* @CreateTime: 2023-02-21 15:46
* @Description: TODO
* @Version: 1.0
*/
public class Adapter extends Target{
private Adaptee adaptee=new Adaptee();
@Override
public void request(){
adaptee.specificRes();
}
}
package com.insound.commontest.util.adaptee;
/**
* @Author: GZ
* @CreateTime: 2023-02-21 15:45
* @Description: TODO
* @Version: 1.0
*/
public class Target {
public void request(){
System.out.println("sdfa");
}
}
package com.insound.commontest.util.adaptee;
/**
* @Author: GZ
* @CreateTime: 2023-02-21 15:48
* @Description: TODO
* @Version: 1.0
*/
public class ClientDemo {
public static void main(String[] args) {
Target target =new Adapter();
target.request();
}
}
14.jdk动态代理模式
//真是对象与代理对象共同实现类
public interface SaleComputer {
void show();
}
//具体类
public class Lenovo implements SaleComputer{
@Override
public void show() {
System.out.println("展示电脑");
}
}
//代理类
public class ProxyTest {
public static void main(String[] args) {
Lenovo lenovo = new Lenovo();
/*
* java.lang.reflect.Proxy提供用于创建动态代理类和实例的静态方法,大家可以查看JDK文档。
* 1.Proxy.newProxyInstance()通过调用newInstance 方法创建代理实例。
* 2.方法中有三个参数
* ClassLoader loader:定义代理类的类加载器(即真实对象)
* Class<?>[] interfaces:真实对象实现的接口数组
* InvocationHandler h:调用处理程序,执行方法。
*/
SaleComputer proxyInstance = (SaleComputer) Proxy.newProxyInstance(lenovo.getClass().getClassLoader(),
lenovo.getClass().getInterfaces(), new InvocationHandler() {
@Override
//invoke方法是核心代理逻辑思想,代理对象调用的所有方法都会触发该方法执行
//增强方式有三种:1.增强参数 2.增强返回值 3.增强方法体
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/*
* 三个参数
* 1.proxy:就是代理对象本身
* 2.method:代理对象调用的方法,被封装为的对象。简单说 谁在运行调用,这个method就是谁。
* 3.args:代理对象调用方法时,传递的实际参数
*/
//增强方法体
System.out.println("买电脑专车接送");
//修改了方法参数 这里method.invok就是调用方法。
String computer = (String) method.invoke(lenovo, null);
//增强方法体
System.out.println("买电脑免费配送");
//增强返回值
return null;
}
});
proxyInstance.show();
}
}