zoukankan      html  css  js  c++  java
  • 单例模式、策略模式、模板方法设计模式探究

    第一.单例模式

    如果在应用中一个类只能创建一个实例,则这个类被称为单例类,这种模式被称为单例模式,通常用于创建一次实例就需要耗费很多资源或者无需创建多个实例的情况,比如说线程池、数据源,或者spring容器中的单例对象。单例模式创建步骤基本是固定的,即:

    1.私有化无参构造器;

    2.创建私有化的静态的单例类变量;

    3.创建public的静态方法,返回单例类对象

    根据创建私有化静态变量时的初始化不同,分为两种创建方法:饿汉式和懒汉式,见下面代码:

    饿汉式与懒汉式的区别在于,饿汉式在创建私有化的静态单例变量时直接赋值为本单例类对象,而不是在静态方法中再创建本单例类对象,因为饿,等不及了嘛。而懒汉式,因为懒,所以只在逼不得已的情况下采取创建对象。

    饿汉式(推荐使用):线程安全的,因为没有做操作,直接返回。

    class Singleton {
        // 1.私有化无参构造器
        private Singleton() {
        }
    
        // 2.创建私有化的静态的单例类变量,并赋值为新建的单例类对象
        private static Singleton instance = new Singleton();
    
        // 3.创建public 的静态方法,返回值为单例类变量
        public static Singleton getInstance() {
            return instance;
        }
    }

    最简单的懒汉式:

    class Singleton {
        private Singleton() {
        }
    
        private static Singleton instance;
    
        public static Singleton getInstance() {
            if (instance == null) {
                instance = new Singleton();
            }
            return instance;
        }
    }

    但是上面的这个懒汉式是线程不安全的。线程A先得到cpu,判断完instance是null后,cpu切换到线程B,线程B判断instance也是null,执行instance = new Singleton();并返回,之后,cpu切换到线程A。虽然现在instance不是null了,但是线程A以为还是null,还会执行instance = new Singleton();并返回,这样应用中就有两个Singleton实例了,不满足要求。

    上述懒汉式需要改进,用synchronized同步,使用同步代码块或者同步方法,改进后的懒汉式:

    class Singleton {
        private Singleton() {
        }
    
        private static Singleton instance;
    
        public static synchronized Singleton getInstance() {
            if (instance == null) {
                instance = new Singleton();
            }
            return instance;
        }
    }

    综上,由于懒汉式比较复杂,所以如果写单例模式的话,懒汉式和饿汉式相比,最好写饿汉式,比较简单。

    为什么要用单例模式?

    恒昌利通CTO问了一个这样的问题。

    第二.策略模式

    用一句话描述就是 针对一个问题,准备一组算法,并将每一个算法封装起来,使得它们可以互换。策略模式在Hibernate框架和Spring框架中都有很好的体现:

    Hibernate:Hibernate的dialect就是一种典型的策略模式。Dialect类代表各数据库方言的抽象父类,不同数据库的持久化访问存在一些差异,Dialect不同子类就代表一种特定的数据库访问策略。面对不同的数据库,我们需要在hibernate.cfg.xml文件中指定使用哪种Dialect子类即可。

    Spring:Spring的事务机制也是一种典型的策略模式。Spring事务策略是通过PlatformTransactionManager接口体现的,当底层采用不同的持久化技术时,就采用其不同的实现类。例如,用JDBC访问数据库时,就在spring配置文件中配置DataSourceTransactionManager类;用Hibernate访问数据库时就在spring配置文件中配置HibernateTransactionManager类。

    在实际开发中,有可能会切换数据库,本来是mysql数据库,现在要换成sqlserver数据库,这样,我们就可以给一个dao接口写多个实现类,每一个实现类都针对一种数据库,要切换数据库时,我们只需切换dao实现类即可。

    第三.模板方法设计模式
    模板方法设计模式:当功能内部一部分实现是确定,一部分实现是不确定时,就可以把不确定的部分写成抽象的,让子类必须去实现,把确定的部分写成非抽象的,让子类去继承。
    模板方法设计模式在spring框架中有很好的体现。spring提倡面向接口编程,一般来说接口都有一个抽象的实现类,此抽象实现类有多个子类。在抽象实现类中,重写接口的方法,但是在此方法中也调用了抽象类声明的方法,此抽象方法交给子类去实现。
    模板方法设计模式通常和策略模式一起使用。
    还是以spring的事务管理举例,PlatformTransactionManager接口的getTransaction(TransactionDefinition definition)用来创建一个事务对象,接口的抽象实现类AbstractPlatformTransactionManager重写了这个方法,但是在方法中调用的doGetTransaction()方法、doBegin(transaction, definition)开启事务方法却是在本抽象类中声明的抽象方法,这些抽象方法由其子类具体实现,这就是模板方法设计模式。而不同的子类实现细节不一样,这就是策略模式。
  • 相关阅读:
    windows 创建指定大小文件
    python pip命令 报错‘unknow or unsupported command install’
    PyCharm:ModuleNotFoundError: No module named 'selenium'
    毕设图片链接
    本地localhost:端口号(自己设置的Apache的端口号)打不开问题解决了!开心、哭泣
    python之freshman00
    Python之freshman07 面向对象编程jinjie
    Python之freshman08 Socket
    Python之freshman04
    Python之freshman05
  • 原文地址:https://www.cnblogs.com/koushr/p/5873449.html
Copyright © 2011-2022 走看看