• java基础-温故而知新


    1.类和对象(实例)的关系

    类就是对象的抽象(模板),对象就是类的实例

    2.java设置模式--代理模式

    定义:代理就是中介,例如租房子经常有中介,还有出票软件 飞猪,携程。

    3.代理大纲分为两种:静态代理与动态代理,主要区别在于代理对象是自定义还是系统生成。自定义的为静态代理,自动生成的为动态代理

    4.静态代理--举一个我们生活中买房子的事情中介事情

    package jav.com.study.proxy.staticProxy;
    //这是我们生活中买房子的事情中介事情
    public interface SellHome {
        public void sell();
    }
    

      

    package jav.com.study.proxy.staticProxy;
    //这是目标类--房子开发商
    public class Developer implements SellHome {
        @Override
        public void sell() {
            System.out.println("这是开发商建造后需要销售的房子");
        }
    }
    
    package jav.com.study.proxy.staticProxy;
    //这是代理,即为中介
    public class Medium implements SellHome{
    
        SellHome sellHome;
        Medium(SellHome sellHome){
            this.sellHome=sellHome;
        }
    
        @Override
        public void sell() {
            System.out.println("买房子前咨询一下");
            System.out.println("买房子前参观");
            System.out.println("买房子签合同");
            sellHome.sell();
            System.out.println("买房子付款");
        }
    }
    

      

    以上有我们生活中的行为类(接口),还有目标类(开发商的房子售卖的事情),中介,现在做一下用户测试

    package jav.com.study.proxy.staticProxy;
    
    public class Client {
        public static void main(String[] args) {
            //创建中介,传入target
            SellHome sellHome=new Medium(new Developer());
            sellHome.sell();
        }
    }
    

      

    Connected to the target VM, address: '127.0.0.1:54952', transport: 'socket'
    Disconnected from the target VM, address: '127.0.0.1:54952', transport: 'socket'
    买房子前咨询一下
    买房子前参观
    买房子签合同
    这是开发商建造后需要销售的房子
    买房子付款
    
    Process finished with exit code 0
    

    静态代理比较容易理解,简单理解就是,中介拿到了目标类的对象,然后在目标对象的前后做手脚

    5.动态代理 --有JDK动态代理,CGLib动态代理等,我们就讲JDK动态代理---还是买房子这件事情

    首先不变的有两个类--- 开发商目标类Developer,还有我们买房子这件事 SellHome

    然后先跟大家隆重介绍两个新角色 ,不然都不敢说自己是动态代理了,不然怎么和静态代理区别呢

    (1)InvocationHandler 这是一个处理器,主要就是每次要执行目标方法的时候,都会跑到InvocationHandler里面的invoke方法(到现在我都不知道底层是怎么实现的,不过我猜测可能是对目标类的各种方法做了listener监听)

      (2)Proxy类,刚刚我们说动态代理的代理对象是系统生成的,其实就是Proxy这个大佬生成的

    有这两个角色,我们接着讲,我们还得创建一个实现InvocationHandler接口的实现类,创建的时候,把目标对象传给SellHandler,他就像会对目标对象盯得紧紧的

    package jav.com.study.proxy.dynamicProxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    public class SellHandler implements InvocationHandler {
        Object target;
    
        SellHandler(Object o){
            this.target=o;
        }
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("买房子前咨询一下");
            System.out.println("买房子前参观");
            System.out.println("买房子签合同");
            method.invoke(this.target,args);
            System.out.println("买房子付款");
            return null;
        }
    }
    

      

    其次创建Client,我们来看一下

    package jav.com.study.proxy.dynamicProxy;
    
    import java.lang.reflect.Proxy;
    
    public class Client {
        public static void main(String[] args) {
            //第一步创建目标类
            SellHome sellHome=new Developer();
            //第二步创建控制类
            SellHandler sellHandler=new SellHandler(sellHome);
            //第三步创建代理对象
            SellHome proxy= (SellHome) Proxy.newProxyInstance(sellHome.getClass().getClassLoader(),
                    sellHome.getClass().getInterfaces(),sellHandler);
            //第四步骤代理类调用目标类方法
            proxy.sell();
        }
    }
    

      

    Connected to the target VM, address: '127.0.0.1:56137', transport: 'socket'
    Disconnected from the target VM, address: '127.0.0.1:56137', transport: 'socket'
    买房子前咨询一下
    买房子前参观
    买房子签合同
    这是开发商建造后需要销售的房子
    买房子付款
    
    Process finished with exit code 0
    

     效果是一样的

    动态代理肯定是比静态代理好,少写很多代码,统一处理

    ---今天20200504

    研究了一下cglib动态代理

    这个比jdk动态代理更强大--不分是否有接口

    就是给我们的目标类创建一个代理类,那么我们得有目标类,即如下

    // 目标类
    public class CglibClass {
        public final void testHideFinal(){
            System.out.println("这是不能展示的");
        }
        public  void testShowFinal(){
            System.out.println("这是可以展示的");
        }
    }
    

     还有生成代理类的类,我们就叫代理工厂吧

    //代理工厂
    public class CGLibProxy implements MethodInterceptor {
        Object o;
    
        public Object createProxyObject(Object obj){
            this.o=obj;
            Enhancer enhancer=new Enhancer();
            enhancer.setSuperclass(obj.getClass());
            enhancer.setCallback(this);
            Object newProxy=enhancer.create();
            return newProxy;
        }
        @Override
        public Object intercept(Object p, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
    
            System.out.println("开始进行权限检测");
            Object ret=method.invoke(o,objects);
            System.out.println("检测完毕");
            return ret;
        }
    }
    

    -- 接下来测试

    public class ProxyTest {
        public static void main(String[] args) {
            CGLibProxy cgLibProxy=new CGLibProxy();
            CglibClass cglibClass= (CglibClass) cgLibProxy.createProxyObject(new CglibClass());
            cglibClass.testHideFinal();
            cglibClass.testShowFinal();
        }
    }
    

     -- 输出

    这是不能展示的   
    开始进行权限检测
    这是可以展示的
    检测完毕
    
    Process finished with exit code 0
    

      

     注意:这里为什么testHideFinal()前后没有进行权限检测呢?这是因为使用了final的方法,使得新创建的代理类不能够继承,所以就没有前后输出检测的信息

    ---今天是2019.10.15 我温故一下

    二.工厂方法模式

    工厂方法主要是吧对象的生产和使用分离开,主要涉及的类有四个,抽象工厂,具体工厂,抽象产品,具体产品(参考出自http://c.biancheng.net/view/1348.html)

    具体代码:

    创建一个接口 Product

    class Interface Product{
        public void show();
    }    

    然后创建实现类

    class Product1 implement Product{
        public void show{
           System.out.print("这是产品1");
        }
    }    
    
    class Product2 implement Product{
        public void show{
           System.out.print("这是产品2");
        }
    }    

    创建抽象工厂

    Class Interface ProductFactory{
      public Product  getProduct();
    }

    创建抽象工厂实现类

    Class ProductFactory1 implement ProductFactory{
        public Product getProduct(){
          System.out.print("工厂1->创建产品1"); 
        }
    }
    
    Class ProductFactory2 implement ProductFactory{
        public Product getProduct(){
          System.out.print("工厂2->创建产品2"); 
        }
    }

    最后写测试

    Class ClientTest{
        public static void main(String[] args){
            //获取配置信息,具体可以自己写一个
            ProductFactory pf=(ProductFactory) ReadXML1.getObject();
            Product p=pf.getProduct();
            p.show();
        }
    }    

    三.抽象工厂模式

    比较工厂模式,竖向多了一个产品等级

  • 相关阅读:
    golang 数据结构 优先队列(堆)
    leetcode刷题笔记5210题 球会落何处
    leetcode刷题笔记5638题 吃苹果的最大数目
    leetcode刷题笔记5637题 判断字符串的两半是否相似
    剑指 Offer 28. 对称的二叉树
    剑指 Offer 27. 二叉树的镜像
    剑指 Offer 26. 树的子结构
    剑指 Offer 25. 合并两个排序的链表
    剑指 Offer 24. 反转链表
    剑指 Offer 22. 链表中倒数第k个节点
  • 原文地址:https://www.cnblogs.com/imfjj/p/11603135.html
Copyright © 2020-2023  润新知