zoukankan      html  css  js  c++  java
  • 简单的设计模式

    一,单例模式

    顾名思义,单例对象能保证在一个JVM中,该对象只有一个实例存在。

    饿汉式:立即记载,线程安全,对象过早创建容易占用内存,资源浪费

    public class Singleton {

    //创建 SingleObject 的一个对象
    private static Singleton singleton = new Singleton();

    //让构造函数为 private,这样该类就不会被实例化
    private Singleton(){}

    //获取唯一可用的对象
    public static Singleton getSinglton(){
    return singleton;
    }

    public void showMessage(){
    System.out.println("Hello World!");
    }
    }

    调用:

    public class SingletonPatternDemo {
    public static void main(String[] args) {

    //不合法的构造函数
    //编译时错误:构造函数 SingleObject() 是不可见的
    //SingleObject object = new SingleObject();

    //获取唯一可用的对象
    Singleton object = Singleton.getSinglton();

    //显示消息
    object.showMessage();
    }
    }

    1,为什么要创建一个private Singlton(){}无参构造?

    禁止其他程序创建该类的对象

    2,为什么本类new出来的对象要私有和静态化?

    私有是不能直接访问,通过指定方法访问,也是封装的体现。静态修饰是因为单例对象singlton能够被外部调用,调用方法getSinglton是静态的,所以对象必须也是静态的

     

    懒汉式

    延迟加载,降低内存消耗,线程不安全,如果想要线程安全需要增加sycronized关键字

    public class Singleton {

    //创建 SingleObject 的一个对象
    private static Singleton singlton;

    //让构造函数为 private,这样该类就不会被实例化
    private Singleton(){}

    //获取唯一可用的对象
    public static Singleton getSinglton(){
    if(singlton==null){
    singlton = new Singleton();
    }
    return singlton;
    }

    public void showMessage(){
    System.out.println("Hello World!");
    }
    }

    加了锁之后懒汉式效率会降低,如何提高效率?

    DCL双检查锁机制。

    1,拿到锁之前检查是否是空对象,2,new对象之前检查是否是空对象

    为什么拿锁前要判断?因为要提高效率,已有对象直接跳过,不用去争夺锁

    为什么new对象之前还要判断?因为这里的singltonSinglton对象的引用,前一个线程如果已经创建了对象那么singlton就不是null,不做判断下一个线程进来就会重复new对象,就不是单例了。

    为什么要加volatile关键字?

    因为假设一个线程new出一个对象的时候,还没执行init()构造方法,就发生了指令重排序,没来的及赋值就指向了对象的引用,这个值就是0。此时另一个线程来了,判断对象不为空就拿去用了,使用了半初始化状态的对象。为了避免发生这种问题所以加入volatile关键字

    public class Singleton {
    
        //创建 SingleObject 的一个对象
        private static volatile Singleton singleton;
    
        //让构造函数为 private,这样该类就不会被实例化
        private Singleton(){}
    
        //获取唯一可用的对象
        public static Singleton getSinglton(){
            // 第一次检查instance是否被实例化出来,如果没有进入if块
            if(singleton == null) {
                synchronized (Singleton.class) {
            // 某个线程取得了类锁,实例化对象前第二次检查instance是否已经被实例化出来,如果没有,才最终实例出对象
                    if (singleton == null) {
                        singleton = new Singleton();
                    }
                }
            }
            return singleton;
        }
    
        public void showMessage(){
            System.out.println("Hello World!");
        }
    }

    二,装饰者模式

    装饰者模式允许向一个现有的对象添加新的功能,同时又不改变其结构。它是作为现有的类的一个包装。

    装饰者模式和静态代理很类似,装饰者(Decorator)和被装饰者(Decoratee)都实现一个接口,都是修改原有被装饰、被代理的方法。

    区别在于装饰者模式构造方法不一样,被装饰对象是直接传过去的,而静态代理是直接new的代理对象

    代理模式注重的是对对象的某一功能的流程把控和辅助,代理类可以对它的客户隐藏一个对象的具体信息,它可以控制对象做某些事;装饰模式注重的是对对象功能的扩展,不关心外界如何调用,只注重对对象功能加强,装饰后还是对象本身。

    装饰者模式用途:IO流,层层增强功能。

    三,代理模式

    静态代理的缺陷:程序员要手动为每一个目标类编写对应的代理类。动态代理解决了这个问题。

    JDK动态代理:

    主要提供2个类Proxy和InvocationHandler

    Proxy.newProxyInstance()用于创建代理对象的实例,InvocationHandler.invoke()用于实现代理对象的方法增强细节

    JDK的动态代理使用Java的反射技术生成动态代理类,只能代理实现了接口的类, 没有实现接口的类不能实现动态代理。

    CGLIB动态代理运行时动态的生成一个被代理类的子类(通过ASM字节码处理框架实现),子类重写了被代理类中所有非final的方法,在子类中采用方法拦截的技术拦截所有父类方法的调用,不需要被代理类对象实现接口,从而CGLIB动态代理效率比Jdk动态代理反射技术效率要高。

     四,工厂模式

    一个接口有多个实现类的情况下,具体创建哪个实现类的对象交由工厂去管理,也就是当需要用哪个子类的时候就由工厂去new哪个子类

  • 相关阅读:
    EntityFramework优缺点
    领导者与管理者的区别
    七个对我最好的职业建议(精简版)
    The best career advice I’ve received
    Difference between Stored Procedure and Function in SQL Server
    2015年上半年一次通过 信息系统项目管理师
    Difference between WCF and Web API and WCF REST and Web Service
    What’s the difference between data mining and data warehousing?
    What is the difference between a Clustered and Non Clustered Index?
    用new创建函数的过程发生了什么
  • 原文地址:https://www.cnblogs.com/yeg0zj/p/14469264.html
Copyright © 2011-2022 走看看