天天看点

Java代理模式、单例模式和工厂模式一、代理模式:二、单例模式:三、工厂模式:四、工厂模式的小应用:五、Spring中用到了工厂模式和单例模式:六、其他设计模式:七、适配器模式:八、模板模式:

参考:

小猴子博客.http://www.monkey1024.com/%e8%ae%be%e8%ae%a1%e6%a8%a1%e5%bc%8f/1482

小猴子博客.http://www.monkey1024.com/%e8%ae%be%e8%ae%a1%e6%a8%a1%e5%bc%8f/1487

单例模式.https://www.runoob.com/design-pattern/singleton-pattern.html

浏览器设置代理.https://blog.csdn.net/weixin_42419856/article/details/81088665

文章目录

  • 一、代理模式:
      • 1.话说代理:
      • 2.静态代理和动态代理:
          • (1)静态代理:我找中间人,中间人找XiaoMan:
          • (2)动态代理:
  • 二、单例模式:
      • 懒汉式和饿汉式:
  • 三、工厂模式:
      • 1.简单工厂模式(静态工厂):
      • 2.工厂方法模式:
      • 3.抽象工厂:
  • 四、工厂模式的小应用:
      • 1.复习工厂模式(简单工厂模式):
      • 2.properties文件的应用:
      • P.S:资源文件+反射+IO流:
      • 3.资源文件+反射的简单工厂模式:
  • 五、Spring中用到了工厂模式和单例模式:
      • 1.配置Spring:
      • 2.Spring中用到了工厂模式:
      • 3.Spring中用到了单例模式:
  • 六、其他设计模式:
  • 七、适配器模式:
  • 八、模板模式:

一、代理模式:

1.话说代理:

代理是什么意思?

我要打官司,但我对法律不太了解,于是请了个律师,让他代理我处理;

鄙人大学做了一个产品,被阿里相中了,阿里公司派来一个主管代理马云和我洽谈;

我们可以在浏览器设置一个代理服务器,用它来上网;

相信大家已经有所体会了,代理就是可以联系双方的中间人。

2.静态代理和动态代理:

详细介绍请点击这里

(1)静态代理:我找中间人,中间人找XiaoMan:

①Beauty接口:

Java代理模式、单例模式和工厂模式一、代理模式:二、单例模式:三、工厂模式:四、工厂模式的小应用:五、Spring中用到了工厂模式和单例模式:六、其他设计模式:七、适配器模式:八、模板模式:

②XiaoMan,You要调用的目标对象:

Java代理模式、单例模式和工厂模式一、代理模式:二、单例模式:三、工厂模式:四、工厂模式的小应用:五、Spring中用到了工厂模式和单例模式:六、其他设计模式:七、适配器模式:八、模板模式:

③静态代理中间人NaNa:

Java代理模式、单例模式和工厂模式一、代理模式:二、单例模式:三、工厂模式:四、工厂模式的小应用:五、Spring中用到了工厂模式和单例模式:六、其他设计模式:七、适配器模式:八、模板模式:

④You:

Java代理模式、单例模式和工厂模式一、代理模式:二、单例模式:三、工厂模式:四、工厂模式的小应用:五、Spring中用到了工厂模式和单例模式:六、其他设计模式:七、适配器模式:八、模板模式:

⑤测试类:

Java代理模式、单例模式和工厂模式一、代理模式:二、单例模式:三、工厂模式:四、工厂模式的小应用:五、Spring中用到了工厂模式和单例模式:六、其他设计模式:七、适配器模式:八、模板模式:

You调用makeFriend(),就是调用beauty.eat(),这里的beauty是naNa,

naNa的eat方法是beauty.eat(),这里的brauty是XiaoMan,

所以最终执行的是XiaoMan的eat()方法,You调用了XiaoMan的方法。

(2)动态代理:

动态代理就是你告诉Java一些参数,它来帮你自动生成中间的代理类。

JDK提供动态代理,底层使用反射原理,

但只能创建接口的代理,即例子中必须实现Beauty接口:

第一个参数是 目标类的类加载器;

第二个参数是 目标类的接口;

第三个参数是 InvocationHandler,代理中 实现的功能 写在该对象中;

通过这三个参数,得到代理类的对象。

第三个参数InvocationHandler的 invoke方法:调用代理类中的任何方法,此方法都会执行;

它的三个参数:

Object proxy: jdk创建出来的的动态代理对象自身的引用,Object类型的引用;

Method method:你要执行调用目标对象的哪个方法,比如XiaoMan的eat();

Object[] args:当前被调用方法用到的参数,比如eat()方法的参数,这里没参数,数组为空;

①测试类:

public class Test {
    public static void main(String[] args) {
   		Beauty xiaoMan = new XiaoMan();

        //不需要自己创建代理了
        //NaNa naNa = new NaNa(xiaoMan);

		//由jdk动态的为你创建一个代理
		Beauty bproxy = 
		//java.lang.reflect.Proxy包导入,创建代理,传三个参数
		(Beauty)Proxy.newProxyInstance(
		xiaoMan.getClass().getClassLoader(),//目标类的类加载器
		xiaoMan.getClass().getInterfaces(),//目标类的接口(jdk动态代理,只能创建目标类实现接口的代理对象)
		new InvocationHandler() {//匿名内部类,重写invoke方法
         	   @Override             //invoke方法也要传三个参数
         	   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {       	  		 
         	       System.out.println("吃饭之前的准备");
         	       Object invoke = method.invoke(xiaoMan);//操作的对象是xiaoMan,
         	       										  //在这里真正调用Xiaoman的eat()方法
         	       System.out.println("吃饭之后的结果");
          	      return invoke;//返回Object对象
          		 }
                   });

        You you = new You(bproxy);

        you.makeFriend();
    }
}
           

②调用有参数的方法:

Java代理模式、单例模式和工厂模式一、代理模式:二、单例模式:三、工厂模式:四、工厂模式的小应用:五、Spring中用到了工厂模式和单例模式:六、其他设计模式:七、适配器模式:八、模板模式:

修改之前的测试类如下,送礼物的时候,为了感谢代理人,所以每次会把礼物分一半给代理人:

Beauty xiaoMan = new XiaoMan();

    //不需要自己创建代理了
    //NaNa naNa = new NaNa(xiaoMan);

    //由jdk动态的为你创建一个代理
    Beauty proxy = (Beauty)Proxy.newProxyInstance(xiaoMan.getClass().getClassLoader(), xiaoMan.getClass().getInterfaces(), new InvocationHandler() {
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("准备");
            Object invoke = null;
            //makeFriend()和show()方法都会走到这里,需要加一个判断,根据方法名来判断
            if ("gift".equals(method.getName())){
                invoke = method.invoke(xiaoMan,new Object[]{(Integer)args[0]/2});//参数变换,
                												//args[0]为10,是方法method传的参数
                												//中间商抽取一半礼物,(Integer)args[0]/2}
            }else{//"eat".equals(method.getName())
                invoke = method.invoke(xiaoMan);
            }

            System.out.println("结果");
            return invoke;//返回invoke
        }
    });

    You you = new You(proxy);

    you.makeFriend();
    you.show();
           

ps:我的理解:

静态代理:我调用Nana,Nana调用XiaoMan;

动态代理:我调用系统的接口,这个接口通过反射调用XiaoMan。

二、单例模式:

单例类只能有一个实例,你要用,就通过函数去取这一个实例。

①创建一个单例类。

public class SingleObject {
 
   //创建 SingleObject 的一个对象
   private static SingleObject instance = new SingleObject();
 
   //让构造函数为 private,这样该类就不会被实例化
   private SingleObject(){}
 
   //获取唯一可用的对象
   public static SingleObject getInstance(){
      return instance;
   }
 
   public void showMessage(){
      System.out.println("Hello World!");
   }
}
           

②从单例类获取唯一的对象。

public class SingleTest {
   public static void main(String[] args) {
 
      //不合法的构造函数
      //编译时错误:构造函数 SingleObject() 是不可见的
      //SingleObject object = new SingleObject();
 
      //获取唯一可用的对象
      SingleObject object = SingleObject.getInstance();
 
      //显示消息
      object.showMessage();
   }
}
           

懒汉式和饿汉式:

true true

Java代理模式、单例模式和工厂模式一、代理模式:二、单例模式:三、工厂模式:四、工厂模式的小应用:五、Spring中用到了工厂模式和单例模式:六、其他设计模式:七、适配器模式:八、模板模式:

三、工厂模式:

我们生活中要用斧子,不可能现做,而是去工厂里面买;

编程中我们要用对象,不用自己new,而是从工厂中去取。

这样,可以降低程序之间的耦合度,

所以,以后创建对象的工作就交给

1.简单工厂模式(静态工厂):

详细介绍请点击这里

工厂根据字符串,返回相应的对象

2.工厂方法模式:

详细介绍请点击这里

工厂接口下实现不同的工厂

3.抽象工厂:

详细介绍请点击这里

相比于工厂方法模式,在其中多写几个方法

四、工厂模式的小应用:

1.复习工厂模式(简单工厂模式):

①先创建一个水果工厂:

Java代理模式、单例模式和工厂模式一、代理模式:二、单例模式:三、工厂模式:四、工厂模式的小应用:五、Spring中用到了工厂模式和单例模式:六、其他设计模式:七、适配器模式:八、模板模式:

②创建水果接口、苹果类、葡萄类:

Java代理模式、单例模式和工厂模式一、代理模式:二、单例模式:三、工厂模式:四、工厂模式的小应用:五、Spring中用到了工厂模式和单例模式:六、其他设计模式:七、适配器模式:八、模板模式:
Java代理模式、单例模式和工厂模式一、代理模式:二、单例模式:三、工厂模式:四、工厂模式的小应用:五、Spring中用到了工厂模式和单例模式:六、其他设计模式:七、适配器模式:八、模板模式:

③创建测试类并运行:

Java代理模式、单例模式和工厂模式一、代理模式:二、单例模式:三、工厂模式:四、工厂模式的小应用:五、Spring中用到了工厂模式和单例模式:六、其他设计模式:七、适配器模式:八、模板模式:

小结一下:

这里我们用到了工厂模式,使得类的使用者和创建者分离,

但是,代码可能有需求要修改,比如加入新水果,那么,工厂类的代码就要跟着修改。

所以我们可以使用工厂方法模式,这里,我们用另一个方法,也可以实现不修改源代码更新项目,

那就是用properties资源文件+反射的简单工厂模式。

2.properties文件的应用:

①properties文件是以键值对的形式存储的,

在firstjava项目的propertiesDemo包下,我创建了aa.properties文件如下:

Java代理模式、单例模式和工厂模式一、代理模式:二、单例模式:三、工厂模式:四、工厂模式的小应用:五、Spring中用到了工厂模式和单例模式:六、其他设计模式:七、适配器模式:八、模板模式:

②创建PropertiesDemo类,这个类通过绝对路径加载了这个properties文件,并输出了aa的值

Java代理模式、单例模式和工厂模式一、代理模式:二、单例模式:三、工厂模式:四、工厂模式的小应用:五、Spring中用到了工厂模式和单例模式:六、其他设计模式:七、适配器模式:八、模板模式:

③如果使用绝对路径,假如我拷贝这个项目到另一台电脑上,路径就不对了,

所以,我们可以使用项目路径(相对路径),

创建PropertiesDemo2类,有两种方法来实现获取当前项目的src路径:

Java代理模式、单例模式和工厂模式一、代理模式:二、单例模式:三、工厂模式:四、工厂模式的小应用:五、Spring中用到了工厂模式和单例模式:六、其他设计模式:七、适配器模式:八、模板模式:

P.S:资源文件+反射+IO流:

①接口与实现类:

Java代理模式、单例模式和工厂模式一、代理模式:二、单例模式:三、工厂模式:四、工厂模式的小应用:五、Spring中用到了工厂模式和单例模式:六、其他设计模式:七、适配器模式:八、模板模式:

②资源文件:

Java代理模式、单例模式和工厂模式一、代理模式:二、单例模式:三、工厂模式:四、工厂模式的小应用:五、Spring中用到了工厂模式和单例模式:六、其他设计模式:七、适配器模式:八、模板模式:

③测试类:

Java代理模式、单例模式和工厂模式一、代理模式:二、单例模式:三、工厂模式:四、工厂模式的小应用:五、Spring中用到了工厂模式和单例模式:六、其他设计模式:七、适配器模式:八、模板模式:

3.资源文件+反射的简单工厂模式:

properties文件:属性文件

里面存储的数据是key-value

中间以=或者:或者空格将key和value隔开

如果一行有多个=、:、空格存在

则以最前面出现的作为分隔符

①创建一个新的包,叫做propertiesTry,里面的三个文件和上面一样:

Java代理模式、单例模式和工厂模式一、代理模式:二、单例模式:三、工厂模式:四、工厂模式的小应用:五、Spring中用到了工厂模式和单例模式:六、其他设计模式:七、适配器模式:八、模板模式:
Java代理模式、单例模式和工厂模式一、代理模式:二、单例模式:三、工厂模式:四、工厂模式的小应用:五、Spring中用到了工厂模式和单例模式:六、其他设计模式:七、适配器模式:八、模板模式:
Java代理模式、单例模式和工厂模式一、代理模式:二、单例模式:三、工厂模式:四、工厂模式的小应用:五、Spring中用到了工厂模式和单例模式:六、其他设计模式:七、适配器模式:八、模板模式:

②创建一个properties资源文件,里面是苹果java文件的“包名+类名”,因为一会要用到反射:

Java代理模式、单例模式和工厂模式一、代理模式:二、单例模式:三、工厂模式:四、工厂模式的小应用:五、Spring中用到了工厂模式和单例模式:六、其他设计模式:七、适配器模式:八、模板模式:

③创建工厂类,这里用静态代码块导入properties文件(静态块只执行一次),拿到苹果类的路径,

用反射的方法的方法得到苹果类的实例:

Java代理模式、单例模式和工厂模式一、代理模式:二、单例模式:三、工厂模式:四、工厂模式的小应用:五、Spring中用到了工厂模式和单例模式:六、其他设计模式:七、适配器模式:八、模板模式:

④Test1类用来测试,成功返回苹果对象:

Java代理模式、单例模式和工厂模式一、代理模式:二、单例模式:三、工厂模式:四、工厂模式的小应用:五、Spring中用到了工厂模式和单例模式:六、其他设计模式:七、适配器模式:八、模板模式:

⑤现在,我要加一个Banana类:

Java代理模式、单例模式和工厂模式一、代理模式:二、单例模式:三、工厂模式:四、工厂模式的小应用:五、Spring中用到了工厂模式和单例模式:六、其他设计模式:七、适配器模式:八、模板模式:

⑥这时,我仅仅需要修改properties文件,我就可以通过工厂返回Banana的对象:

Java代理模式、单例模式和工厂模式一、代理模式:二、单例模式:三、工厂模式:四、工厂模式的小应用:五、Spring中用到了工厂模式和单例模式:六、其他设计模式:七、适配器模式:八、模板模式:
Java代理模式、单例模式和工厂模式一、代理模式:二、单例模式:三、工厂模式:四、工厂模式的小应用:五、Spring中用到了工厂模式和单例模式:六、其他设计模式:七、适配器模式:八、模板模式:

五、Spring中用到了工厂模式和单例模式:

Spring相当于项目的大管家,其中的一项功能就是管理对象的创建。

官方名词叫做IOC(Inversion of Control) 控制反转 ,

即把对象创建的控制权有你来new反转为spring来做,

再将创建好的对象注入给使用者,就是 依赖注入 了。

1.配置Spring:

详细配置过程点击这里

大概步骤是:

①添加依赖jar包

②添加spring的配置文件

③用对象时,获取配置文件,再根据配置文件的id用反射的方式创建对象

2.Spring中用到了工厂模式:

详细用法点击这里

通过控制反转获取的对象,有三种方式:

①默认方式

②实例工厂

③静态工厂

3.Spring中用到了单例模式:

详细用法点击这里

用控制反转创建的对象,默认都是单例模式的,如果有需要,

也可以在spring配置文件的属性中,修改tpye属性,改为别的模式。

singleton: 单例模式,默认。

prototype: 原型模式。即每次使用 getBean 方法获取的的实例都是一个新的实例。

request:对于每次 HTTP 请求,都将会产生一个不同的 Bean 实例。

session:对于每个不同的 HTTP session,都将产生一个不同的 Bean 实例。

application:在一个web应用中会产生一个bean实例,就相当于在一个ServletContext中只有该bean的实例。

websocket:在一个websocket中会产生一个bean实例。

六、其他设计模式:

1.工厂模式:创建实例不用自己去new,而是从工厂中获取;

2.代理模式:找了一个代理类来当中介,NaNa,来创建对象‘

3.桥接模式:JFBC提供统一入口;

4.装饰器模式:不想继承,但又想修改某一方法,和代理模式区别在需要传入实例;

5.组合模式:树和节点;

6.外观模式:电脑与CPU、Disk、Memory的关系,统一外观方法名 ;

7.享元模式:池,Final,HashMap容器键值对;

8.原型模式:浅拷贝共用内存,深拷贝不共用,Java对象默认浅拷贝;

9.单例模式:控制用的对象都是一个,构造器私有;

10.适配器模式(类、对象、接口):覆盖操作;

11.策略模式:接口可以多个实现,策略选择;

12.模板模式:final模板永远调用;

13观察者模式:创建观察者、主题,主题add观察者,主题更新通知观察者;

14.迭代器模式:集合,迭代;

15.责任链模式:链表;

16.命令模式:Linux;

17.备忘录模式:备份恢复,命令根据不同执行者做不同操作 ;

18.状态模式:QQ上线下线;

七、适配器模式:

原本实现Servlet接口的Servlet类要实现很多方法,比如init、service、destory方法等

GenericServlet类用了适配器模式:

现在servlet只需继承GenericServlet类,实现service方法

GenericServlet类已经实现了Servlet, ServletConfig接口

适配器是一个万能充电接口,

充电接口(GenericServlet类)一端连接安卓手机的充电器(servlet),

另一端连接苹果手机(service接口),这样就实现了使用安卓手机的充电器给苹果手机充电了。

八、模板模式:

定义抽象类,里面有抽象方法,让子类必须自己实现这些抽象方法

HttpServlet使用了模板模式,它里面会运行doGet方法,

自己也写了doGet方法,但里面没写啥,希望继承类去自己实现。