GoF23种设计模式

23种设计模式

设计模式的分类 总体来说设计模式分为三大类:

创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

OOP七大原则

开闭原则:对扩展开放,对修改关闭

里氏替换原则:继承必须确保超累所拥有的性质在子类中任然成立(尽量不重写父类的方法)

依赖倒置原则:要面向接口编程,不要面向实现编程

单一职责原则:控制类的粒度大小、将对象解耦、提高其内聚性

接口隔离原则:要为各个类创建他们需要的专用接口

迪米特法则:只与你的直接朋友交谈,不跟“陌生人”说话

合成复用原则:尽量先试用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现


创建型模式

工厂模式

简单工厂模式

:简单工厂模式是属于创建型模式,又叫做静态工厂方法模式

例如:(直接看代码)

先写一个接口

 public interface Car {
     void name();
 }

定义他的工厂类

 //静态工厂模式
 //增加一个新的产品,如果不修改代码,做不到!
 ​
 //开闭原则
 public class CarFactory {
 ​
     //方法一:
     public static Car getCar(String car){
         if (car.equals("五菱")){
             return new WuLing();
         }else if (car.equals("特斯拉")){
             return new Tesla();
         }else {
             return null;
         }
     }
 ​
     //方法二:
     public static Car getWuLing(){
         return new WuLing();
     }
     public static Car getTesla(){
         return new Tesla();
     }
 }

汽车的品牌实现接口

 public class Dazhong implements Car{
     @Override
     public void name() {
         System.out.println("大众!");
     }
 }
 public class Tesla implements Car{
     @Override
     public void name() {
         System.out.println("特斯拉!");
     }
 }
 public class WuLing implements Car{
     @Override
     public void name() {
         System.out.println("五菱宏光!");
     }
 }

消费者买车

 public class Consumer {
     public static void main(String[] args) {
         //接口,所有的实现类!工厂
         //Car car = new WuLing();
         //Car car2 = new Tesla();
 ​
         //2.使用工厂类实现
 ​
         Car car = CarFactory.getCar("五菱");
         Car car2 = CarFactory.getCar("特斯拉");
 ​
         car.name();
         car2.name();
     }
 }

工厂方法模式

:是一种常用的类创建型设计模式,此模式的核心精神是封装类中变化的部分,提取其中个性化善变的部分为独立类,通过依赖注入以达到解耦、复用和方便后期维护拓展的目的。

定义接口

 public interface Car {
     void name();
 }

定义车工厂

 //工厂方法模式
 public interface CarFactory {
     Car getCar();
 }

车品牌工厂 :实现车工厂接口

 public class MoBaiFactory implements CarFactory{
     @Override
     public Car getCar() {
         return new MoBai();
     }
 }
 public class TeslaFactory implements CarFactory{
     @Override
     public Car getCar() {
         return new Tesla();
     }
 }
 public class WuLingFactory implements CarFactory{
     @Override
     public Car getCar() {
         return new WuLing();
     }
 }

汽车:实现Car接口

 public class MoBai implements Car{
     @Override
     public void name() {
         System.out.println("摩拜单车!");
     }
 }
 public class Tesla implements Car {
     @Override
     public void name() {
         System.out.println("特斯拉!");
     }
 }
 public class WuLing implements Car {
     @Override
     public void name() {
         System.out.println("五菱宏光!");
     }
 }

消费者可以直接去车工厂提取车,不需要考虑其他

 public class Consumer {
     public static void main(String[] args) {
         Car car = new WuLingFactory().getCar();
         Car car2 = new TeslaFactory().getCar();
 ​
         car.name();
         car2.name();
         Car car3 = new MoBaiFactory().getCar();
         car3.name();
     }
 }

抽象工厂模式

:抽象工厂是指当有多个抽象角色时使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体情况下,创建多个产品族中的产品对象。

 

 public interface IProductFactory {
 //产品工厂 、生产手机与路由器
     //生产手机
     IphoneProduct  iphoneProduct();
 ​
     //生产路由器
     IRouterProduct routerProduct();
 }
 //手机产品接口
 public interface IphoneProduct {
 ​
     void start();
     void shutdown();
     void callup();
     void sendSMS();
 ​
 }
 public interface IRouterProduct {
 //路由器产品接口
     void start();
     void shutdown();
     void openWifi();
     void setting();
 ​
 }

不同手机工厂:需要实现产品接口,并且重写方法

 public class HuaweiFactory implements IProductFactory{
     @Override
     public IphoneProduct iphoneProduct() {
         return new HuaweiIphone();
     }
 ​
     @Override
     public IRouterProduct routerProduct() {
         return new HuaweiIRouter();
     }
 }
 public class XiaomiFactory implements IProductFactory{
     @Override
     public IphoneProduct iphoneProduct() {
         return new XiaomiPhone();
     }
 ​
     @Override
     public IRouterProduct routerProduct() {
         return new XiaomiIRouter();
     }
 }

不同手机实现手机接口

 //华为手机
 public class HuaweiIphone implements IphoneProduct{
     @Override
     public void start() {
         System.out.println("开启华为手机");
     }
 ​
     @Override
     public void shutdown() {
         System.out.println("关闭华为手机");
     }
 ​
     @Override
     public void callup() {
         System.out.println("华为手机打电话");
     }
 ​
     @Override
     public void sendSMS() {
         System.out.println("华为发短信");
     }
 }
 //小米手机
 public class XiaomiPhone implements IphoneProduct{
     @Override
     public void start() {
         System.out.println("开启小米手机");
     }
 ​
     @Override
     public void shutdown() {
         System.out.println("小米手机关机");
     }
 ​
     @Override
     public void callup() {
         System.out.println("小米打电话");
     }
 ​
     @Override
     public void sendSMS() {
         System.out.println("小米发短信");
     }
 }
 //华为路由器
 public class HuaweiIRouter implements IRouterProduct{
     @Override
     public void start() {
         System.out.println("启动华为路由器");
     }
 ​
     @Override
     public void shutdown() {
         System.out.println("关闭华为路由器");
     }
 ​
     @Override
     public void openWifi() {
         System.out.println("打开华为wifi");
     }
 ​
     @Override
     public void setting() {
         System.out.println("华为设置");
     }
 }
 //小米路由器
 public class XiaomiIRouter implements IRouterProduct{
     @Override
     public void start() {
         System.out.println("启动小米路由器");
     }
 ​
     @Override
     public void shutdown() {
         System.out.println("关闭小米路由器");
     }
 ​
     @Override
     public void openWifi() {
         System.out.println("打开小米wifi");
     }
 ​
     @Override
     public void setting() {
         System.out.println("小米设置");
     }
 }

建造者模式

( Builder ):建造者模式是设计模式的一种,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

例:工地建房子

 //抽象的建造者:方法
 public abstract class Builder {
 ​
     //步骤:A->B->C->D
     abstract void buildA();//地基
     abstract void buildB();//钢筋工程
     abstract void buildC();//铺电线
     abstract void buildD();//粉刷
 ​
     //完工:得到产品
     abstract Product getProduct();
 }
 //产品:房子
 public class Product {
     private String buildA;
     private String buildB;
     private String buildC;
     private String buildD;
 ​
     public String getBuildA() {
         return buildA;
     }
 ​
     public void setBuildA(String buildA) {
         this.buildA = buildA;
     }
 ​
     public String getBuildB() {
         return buildB;
     }
 ​
     public void setBuildB(String buildB) {
         this.buildB = buildB;
     }
 ​
     public String getBuildC() {
         return buildC;
     }
 ​
     public void setBuildC(String buildC) {
         this.buildC = buildC;
     }
 ​
     public String getBuildD() {
         return buildD;
     }
 ​
     public void setBuildD(String buildD) {
         this.buildD = buildD;
     }
 ​
     @Override
     public String toString() {
         return "Product{" +
                 "buildA='" + buildA + '\'' +
                 ", buildB='" + buildB + '\'' +
                 ", buildC='" + buildC + '\'' +
                 ", buildD='" + buildD + '\'' +
                 '}';
     }
 }

定义一个工人类

 public class Worker extends Builder{
 ​
     private Product product;
 ​
     public Worker() {
         product = new Product();
     }
 ​
     @Override
     void buildA() {
         product.setBuildA("地基");
         System.out.println("地基");
     }
 ​
     @Override
     void buildB() {
         product.setBuildB("钢筋工程");
         System.out.println("钢筋工程");
     }
 ​
     @Override
     void buildC() {
         product.setBuildC("铺电线");
         System.out.println("铺电线");
     }
 ​
     @Override
     void buildD() {
         product.setBuildD("粉刷");
         System.out.println("粉刷");
     }
 ​
     @Override
     Product getProduct() {
         return product;
     }
 }

定义指挥者:负责指挥工人

 //指挥:核心。负责指挥构建一个工程,工程如何构建,由他指挥
 public class Director {
     public Product build(Builder builder){
 ​
         //指挥工人按照顺序建房子
         builder.buildA();
         builder.buildB();
         builder.buildC();
         builder.buildD();
 ​
         return builder.getProduct();
     }
 ​
 }

测试:

 public class Test {
     public static void main(String[] args) {
         //指挥
         Director director = new Director();
 ​
         //指挥  具体的工人完成  产品
         Product build = director.build(new Worker());
         System.out.println(build.toString());
     }
 }

 public abstract class Builder {
 ​
 ​
     abstract Builder buildeA(String msg);//汉堡
     abstract Builder buildeB(String msg);//可乐
     abstract Builder buildeC(String msg);//薯条
     abstract Builder buildeD(String msg);//甜点
 ​
     abstract Product getProduct();
 }

套餐

 //产品:套餐
 public class Product {
 ​
     private String BuildA="汉堡";
     private String BuildB="可乐";
     private String BuildC="薯条";
     private String BuildD="甜点";
 ​
     public String getBuildA() {
         return BuildA;
     }
 ​
     public void setBuildA(String buildA) {
         BuildA = buildA;
     }
 ​
     public String getBuildB() {
         return BuildB;
     }
 ​
     public void setBuildB(String buildB) {
         BuildB = buildB;
     }
 ​
     public String getBuildC() {
         return BuildC;
     }
 ​
     public void setBuildC(String buildC) {
         BuildC = buildC;
     }
 ​
     public String getBuildD() {
         return BuildD;
     }
 ​
     public void setBuildD(String buildD) {
         BuildD = buildD;
     }
 ​
     @Override
     public String toString() {
         return "Product{" +
                 "BuildA='" + BuildA + '\'' +
                 ", BuildB='" + BuildB + '\'' +
                 ", BuildC='" + BuildC + '\'' +
                 ", BuildD='" + BuildD + '\'' +
                 '}';
     }
 }
 //具体的建造者
 public class Worker extends Builder{
 ​
     private Product product;
 ​
     public Worker() {
         product = new Product();
     }
 ​
     @Override
     Builder buildeA(String msg) {
         product.setBuildA(msg);
         return this;
     }
 ​
     @Override
     Builder buildeB(String msg) {
         product.setBuildB(msg);
         return this;
     }
 ​
     @Override
     Builder buildeC(String msg) {
         product.setBuildC(msg);
         return this;
     }
 ​
     @Override
     Builder buildeD(String msg) {
         product.setBuildD(msg);
         return this;
     }
 ​
     @Override
     Product getProduct() {
         return product;
     }
 ​
 ​
 }

用户可以自己搭配选择

 public class Test {
     public static void main(String[] args) {
 ​
         //服务员
         Worker worker = new Worker();
 ​
         //链式编程  : 在原来的基础上,可以*组合了,如果不组合,也有默认的套餐
         Product product = worker.buildeA("全家桶").buildeB("雪碧")
                 .getProduct();
         System.out.println(product.toString());
     }
 }

原型模式

:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

复制拷贝: 第一个方案复制的会跟之前的共用一个时间

 /*
 1.实现一个接口     Cloneable
 2.重写一个方法     clone()
 */
 ​
 ​
 //Video
 public class Video implements Cloneable{
 ​
     private String name;
     private Date createTime;
 ​
     @Override
     protected Object clone() throws CloneNotSupportedException {
         return super.clone();
     }
 ​
     public Video() {
     }
 ​
     public Video(String name, Date createTime) {
         this.name = name;
         this.createTime = createTime;
     }
 ​
     public String getName() {
         return name;
     }
 ​
     public void setName(String name) {
         this.name = name;
     }
 ​
     public Date getCreateTime() {
         return createTime;
     }
 ​
     public void setCreateTime(Date createTime) {
         this.createTime = createTime;
     }
 ​
     @Override
     public String toString() {
         return "Video{" +
                 "name='" + name + '\'' +
                 ", createTime=" + createTime +
                 '}';
     }
 }

 

 

 public class Bilibili {
 ​
     public static void main(String[] args) throws CloneNotSupportedException {
         //原型对象  v1
 ​
         Date date = new Date();
         Video v1 = new Video("狂神说JAVA", date);
         System.out.println("v1=>"+v1);
         System.out.println("v1=>hash"+v1.hashCode());
 ​
         //v1  克隆  v2
         //Video v2 = new Video("狂神说JAVA", date);
         Video v2 = (Video) v1.clone();
         System.out.println("v2=>"+v2);
         System.out.println("v2=>hash"+v2.hashCode());
 ​
     }
 }

第二个在修改时间的情况下会分隔开

 /*
 1.实现一个接口     Cloneable
 2.重写一个方法     clone()
 */
 ​
 ​
 //Video
 public class Video implements Cloneable{
 ​
     private String name;
     private Date createTime;
 ​
     @Override
     protected Object clone() throws CloneNotSupportedException {
 ​
         Object obj = super.clone();
 ​
         //实现深克隆~  序列化、反序列化
         Video v = (Video) obj;
         v.createTime = (Date)this.createTime.clone();//将这个对象的属性进行克隆
 ​
         return obj;
     }
 ​
     public Video() {
     }
 ​
     public Video(String name, Date createTime) {
         this.name = name;
         this.createTime = createTime;
     }
 ​
     public String getName() {
         return name;
     }
 ​
     public void setName(String name) {
         this.name = name;
     }
 ​
     public Date getCreateTime() {
         return createTime;
     }
 ​
     public void setCreateTime(Date createTime) {
         this.createTime = createTime;
     }
 ​
     @Override
     public String toString() {
         return "Video{" +
                 "name='" + name + '\'' +
                 ", createTime=" + createTime +
                 '}';
     }
 }

 

 

 //Spring Bean:单例模式,原型模式~
 // 原型模式 + 工厂模式 ==> new <==> 原型模式
 ​
 public class Bilibili {
 ​
     public static void main(String[] args) throws CloneNotSupportedException {
 ​
         //原型对象  v1
 ​
         Date date = new Date();
         Video v1 = new Video("狂神说JAVA", date);
         Video v2 = (Video) v1.clone();
 ​
         System.out.println("v1=>"+v1);
         System.out.println("v2=>"+v2);
         System.out.println("======================");
         date.setTime(231321312);
 ​
         System.out.println("v1=>"+v1);
         System.out.println("v2=>"+v2);
 ​
      /*
         //原型对象  v1
 ​
         Date date = new Date();
         Video v1 = new Video("狂神说JAVA", date);
         System.out.println("v1=>"+v1);
         System.out.println("v1=>hash"+v1.hashCode());
 ​
         //v1  克隆  v2
         //Video v2 = new Video("狂神说JAVA", date);
         Video v2 = (Video) v1.clone();
         System.out.println("v2=>"+v2);
         System.out.println("v2=>hash"+v2.hashCode());
     */
     }
 }

结构型模式

适配器模式

:是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。

这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。

GoF23种设计模式

 //接口转换器的抽象实现
 public interface NetToUsb {
 ​
     //作用:处理请求,网线=>usb
     public void handleRequest();
 }
 //要被适配的类    :网线
 public class Adaptee {
 ​
     public void request(){
 ​
         System.out.println("连接网线上网");
     }
 }
 //1.继承  (类适配器,单继承)----
 //2.组合  (对象适配器,常用)
 ​
 ​
 //真正的适配器~,需要连接USB,连接网线~
 public class Adapter extends Adaptee implements NetToUsb{
 ​
     @Override
     public void handleRequest() {
         super.request();//可以上网了~
     }
 }
 //1.继承  (类适配器,单继承)
 //2.组合  (对象适配器,常用)------
 ​
 ​
 //真正的适配器~,需要连接USB,连接网线~
 public class Adapter2  implements NetToUsb{
 ​
     private Adaptee adaptee;
 ​
     public Adapter2(Adaptee adaptee) {
         this.adaptee = adaptee;
     }
 ​
     @Override
     public void handleRequest() {
         adaptee.request();//可以上网了~
     }
 }
 //客户端类:想上网,插不上网线~
 public class Computer {
 ​
     //我们的电脑需要连接上转接器才可以上网
     public void net(NetToUsb adapter) {
         //上网的具体实现~,找一个转接头
         adapter.handleRequest();
     }
 ​
 ​
     public static void main(String[] args) {
         //电脑,网线,适配器~
         Computer computer = new Computer();//电脑
         Adaptee adaptee = new Adaptee();//网线
         Adapter2 adapter = new Adapter2(adaptee);//转接器  (比较完美的实现)
         //Adapter adapter = new Adapter();//转接器
 ​
 ​
         computer.net( adapter);
     }
 }

桥接模式

:是将抽象部分与它的实现部分分离,使它们都可以独立地变化。它是一种对象结构型模式,又称为柄体(Handle and Body)模式或接口(interface)模式。

结构图:

GoF23种设计模式

 //品牌
 public interface Brand {
 ​
     void info();
 ​
 }
 //苹果
 public class Apple implements Brand{
     @Override
     public void info() {
         System.out.print("苹果");
     }
 }
 //联想
 public class Lenovo implements Brand{
     @Override
     public void info() {
         System.out.print("联想");
     }
 }
 //抽象的电脑类
 public abstract class Computer {
 ​
     //组合,品牌~
     protected Brand brand;
 ​
     public Computer(Brand brand) {
         this.brand = brand;
     }
 ​
     public void info(){
         brand.info();//自带品牌
     }
 }
 ​
 class Desktop extends Computer{
     public Desktop(Brand brand) {
         super(brand);
     }
 ​
     @Override
     public void info() {
         super.info();
         System.out.println("台式机");
     }
 }
 ​
 class Laptop extends Computer{
     public Laptop(Brand brand) {
         super(brand);
     }
 ​
     @Override
     public void info() {
         super.info();
         System.out.println("笔记本");
     }
 }

测试类:

 public class Test {
     public static void main(String[] args) {
         //苹果笔记本
         Computer computer = new Laptop(new Apple());
         computer.info();
 ​
         //联想台式机
         Computer computer2 = new Desktop(new Lenovo());
         computer2.info();
     }
 }

结构:(同理上面的图)

GoF23种设计模式


 

代理模式

为什么要学习代理模式?这就是SpringAOP的底层! 【SpringAOP 和 SpringMVC】

代理模式的分类:

  • 静态代理

  • 动态代理

GoF23种设计模式

1.静态代理

角色分析:

  • 抽象角色:一般会使用接口或者抽象类来解决

  • 真是角色:被代理的角色

  • 代理角色:代理真实角色,代理真实角色后一般会做一些附属操作

  • 客户:访问代理对象的人!

 

代码步骤:

1.接口

 //租房
 public interface Rent {
 ​
     public void rent();
 }

2.真实角色

 //房东
 public class Landlord implements Rent{
     @Override
     public void rent() {
         System.out.println("房东要出租房子!");
     }
 }

3.代理角色

 public class Proxy implements Rent{
 ​
     private Landlord landlord;
 ​
     public Proxy() {
     }
 ​
     public Proxy(Landlord landlord) {
         this.landlord = landlord;
     }
 ​
     @Override
     public void rent() {
         seeHouse();
         landlord.rent();
         hetong();
         fee();
     }
 ​
     public void seeHouse(){
         System.out.println("中介带你看房");
     }
 ​
     public void fee(){
         System.out.println("收中介费");
     }
 ​
     public void hetong(){
         System.out.println("签租赁合同");
     }
 }

4.客户端访问代理角色

 public class Client {
 ​
     public static void main(String[] args) {
         //房东要出租房子
         Landlord landlord = new Landlord();
         //代理,中介帮房东出租房子,但是呢?代理角色一般会有一些附属操作
         Proxy proxy = new Proxy(landlord);
         //你不用面对房东,直接找中介租房子即可!
         proxy.rent();
     }
 ​
 }

 

代理模式的好处:

  • 可以使真是角色的操作更加纯粹!不用去关注一些公共的业务

  • 公共的业务也就交给代理角色!实现了业务的分工!

  • 公共业务发生拓展的时候,方便集中管理!

缺点:

  • 一个真是角色就会产生一个代理角色:代码量会翻倍~ 开发效率会变低~

2.加深理解静态代理

代码:

1.接口

 public interface UserService {
 ​
     public void add();
     public void delete();
     public void update();
     public void query();
 }

2.实现类

 //真实对象
 public class UserServiceImpl implements UserService{
     @Override
     public void add() {
         System.out.println("增加了一个用户");
     }
 ​
     @Override
     public void delete() {
         System.out.println("删除了一个用户");
     }
 ​
     @Override
     public void update() {
         System.out.println("修改了一个用户");
     }
 ​
     @Override
     public void query() {
         System.out.println("查询了一个用户");
     }
     //1、改动原有的业务代码,在公司中是大忌!
 }

3.代理

 public class UserServiceProxy implements UserService{
 ​
     UserServiceImpl userService;
 ​
     public void setUserService(UserServiceImpl userService) {
         this.userService = userService;
     }
 ​
     @Override
     public void add() {
         log("add");
         userService.add();
     }
 ​
     @Override
     public void delete() {
         log("delete");
         userService.delete();
     }
 ​
     @Override
     public void update() {
         log("update");
         userService.update();
     }
 ​
     @Override
     public void query() {
         log("query");
         userService.query();
     }
 ​
     //日志方法
     public void log(String msg){
         System.out.println("使用了[Debug]"+msg+"方法");
     }
 }

4.客户端访问

 public class Client {
     public static void main(String[] args) {
         UserServiceImpl userService = new UserServiceImpl();
 ​
         UserServiceProxy proxy = new UserServiceProxy();
         proxy.setUserService(userService);
 ​
         proxy.add();
     }
 }

GoF23种设计模式

3.动态代理

  • 动态代理和静态代理角色一样

  • 动态代理的代理类是动态的,不是我们直接写好的!

  • 动态代理分为两大类:基于接口的动态代理,基于类的动态代理

    • 基于接口- - - JDK动态代理【我们在这里使用】

    • 基于类:cglib

    • Java字节码实现:javasist

需要了解两个类:Proxy:代理,InvocationHandler:调用处理程序

 

动态代理的好处:

  • 可以使真是角色的操作更加纯粹!不用去关注一些公共的业务

  • 公共的业务也就交给代理角色!实现了业务的分工!

  • 公共业务发生拓展的时候,方便集中管理!

  • 一个动态代理类代理的是一个接口,一般就是对应的一类业务

  • 一个动态代理类可以代理多个类,只要是实现了同一个接口即可!

代码:

1.接口

 //租房
 public interface Rent {
 ​
     public void rent();
 }

2.真实对象

 //房东
 public class Landlord implements Rent {
     @Override
     public void rent() {
         System.out.println("房东要出租房子!");
     }
 }

3.代理

 public class ProxyInvocationHandler implements InvocationHandler {
 ​
     //被代理的接口
     private Rent rent;
 ​
     public void setRent(Rent rent) {
         this.rent = rent;
     }
 ​
     //生成得到代理类
     public Object getProxy(){
         return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(),this);
     }
 ​
     @Override
     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
 ​
         //动态代理的本质,就是反射机制的实现!
         seeHouse();
         Object result = method.invoke(rent,args);
         return result;
     }
 ​
     public void seeHouse(){
         System.out.println("中介带看房子");
     }
 }

4.客户端访问对象

 public class Client {
 ​
     public static void main(String[] args) {
         //真实角色
         Landlord landlord = new Landlord();
 ​
         //代理角色:现在没有
         ProxyInvocationHandler pih = new ProxyInvocationHandler();
         //通过调用程序处理角色来处理我们要调用的接口对象!
         pih.setRent(landlord);
         Rent proxy = (Rent) pih.getProxy();//这里的proxy就是动态生成的,我们并没有写!
         proxy.rent();
     }
 }

优化动态代理万能的方法:

 public class ProxyInvocationHandler implements InvocationHandler {
 ​
     //被代理的接口
     private Object target;
 ​
     public void setTarget(Object target) {
         this.target = target;
     }
 ​
 ​
     //生成得到代理类
     public Object getProxy(){//最后面的this代表实现的接口  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());
         //动态代理的本质,就是反射机制的实现!
         Object result = method.invoke(target,args);
         return result;
     }
 ​
     public void log (String msg){
         System.out.println("使用了"+msg+"方法");
     }
 }
 public class Client {
     public static void main(String[] args) {
         //真实角色
         UserServiceImpl userService = new UserServiceImpl();
         //代理角色,不存在
         ProxyInvocationHandler pih = new ProxyInvocationHandler();
 ​
         pih.setTarget(userService);//设置要代理的对象
         //动态生成代理类
         UserService proxy = (UserService) pih.getProxy();
         proxy.query();
     }
 }

 

 

上一篇:easyUI datebox 精确到秒并且显示值


下一篇:SpringBoot结果集包装类