×

单例模式有几种实现方式

单例模式有几种实现方式(Python中的单例模式的几种实现方式的及优化)

admin admin 发表于2023-10-31 21:57:11 浏览45 评论0

抢沙发发表评论

本文目录

Python中的单例模式的几种实现方式的及优化

单例模式就是 : 1、类的构造函数为private,即外部程序不能通过new关键字创建对象的实例 2、类中提供一个private static的 类变量引用 ; 3、单例类中提供静态方法 定义为 public static 的方法获取一个类的实例 ; 4、静态方法返回 类的引用,...

数据库链接为什么要用单例模式

数据库链接用单例模式的原因:

1,单例只保留一个对象,可以减少系统资源开销。

2,提高创建速度,每次都获取已经存在的对象因此提高创建速度全局共享对象。

3,单例在系统中只存在一个对象实例,因此任何地方使用此对象都是一个对象避免多实例创建使用时产生的逻辑错误。

例模式是一种常用的软件设计模式,它的核心结构只包含一个被称为单例的特殊类。它的目的是保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。单例模式有3种实现方式:懒汉式、饿汉式和双重锁的形式。

一、 懒汉式

构造函数声明为private或者protect防止被外部函数实例化,内部保存一个private static的类指针保存唯一的实例,实例的动作有一个public的类方法实现。

二、 饿汉式

在GetInstance函数里定义一个静态的实例,可以保证拥有唯一的实例,在返回是需要返回其指针即可。

三、双重锁

在GetInstance函数里定义一个静态的实例,可以保证拥有唯一的实例,在返回是需要返回其指针即可。

Java中单例模式有哪些实现方法

单例模式大致有五种写法,分别为懒汉,恶汉,静态内部类,枚举和双重校验锁。 1、懒汉写法,常用写法 class LazySingleton{ private static LazySingleton singleton; private LazySingleton(){ } public static LazySingleton getInstance(){ i...

spring主要运用那些设计模式,单例模式是怎么实现的

设计模式作为工作学习中的枕边书,却时常处于勤说不用的尴尬境地,也不是我们时常忘记,只是一直没有记忆。

今天,螃蟹在IT学习者网站就设计模式的内在价值做一番探讨,并以spring为例进行讲解,只有领略了其设计的思想理念,才能在工作学习中运用到“无形”。

Spring作为业界的经典框架,无论是在架构设计方面,还是在代码编写方面,都堪称行内典范。好了,话不多说,开始今天的内容。

spring中常用的设计模式达到九种,我们举例说明:

第一种:简单工厂

又叫做静态工厂方法(StaticFactory Method)模式,但不属于23种GOF设计模式之一。 

简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类。 

spring中的BeanFactory就是简单工厂模式的体现,根据传入一个唯一的标识来获得bean对象,但是否是在传入参数后创建还是传入参数前创建这个要根据具体情况来定。如下配置,就是在 HelloItxxz 类中创建一个 itxxzBean。

《beans》

《bean id=“singletonBean“ class=“com.itxxz.HelloItxxz“》

《constructor-arg》

《value》Hello! 这是singletonBean!value》

《/constructor-arg》

《/ bean》

《bean id=“itxxzBean“ class=“com.itxxz.HelloItxxz“

singleton=“false“》

《constructor-arg》

《value》Hello! 这是itxxzBean! value》

《/constructor-arg》

《/bean》

《/beans》

第二种:工厂方法(Factory Method)

通常由应用程序直接使用new创建新的对象,为了将对象的创建和使用相分离,采用工厂模式,即应用程序将对象的创建及初始化职责交给工厂对象。

一般情况下,应用程序有自己的工厂对象来创建bean.如果将应用程序自己的工厂对象交给Spring管理,那么Spring管理的就不是普通的bean,而是工厂Bean。

螃蟹就以工厂方法中的静态方法为例讲解一下:

import java.util.Random;

public class StaticFactoryBean {

public static Integer createRandom() {

return new Integer(new Random().nextInt());

}

}

建一个config.xm配置文件,将其纳入Spring容器来管理,需要通过factory-method指定静态方法名称

《bean id=“random“

class=“example.chapter3.StaticFactoryBean“ factory-method=“createRandom“ //createRandom方法必须是static的,才能找到 scope=“prototype“

/》

测试:

public static void main(String args) {

//调用getBean()时,返回随机数.如果没有指定factory-method,会返回StaticFactoryBean的实例,即返回工厂Bean的实例       XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource(“config.xml“));       System.out.println(“我是IT学习者创建的实例:“+factory.getBean(“random“).toString());

}

第三种:单例模式(Singleton)

保证一个类仅有一个实例,并提供一个访问它的全局访问点。 

spring中的单例模式完成了后半句话,即提供了全局的访问点BeanFactory。但没有从构造器级别去控制单例,这是因为spring管理的是是任意的java对象。 

核心提示点:Spring下默认的bean均为singleton,可以通过singleton=“true|false” 或者 scope=“?”来指定

第四种:适配器(Adapter)

在Spring的Aop中,使用的Advice(通知)来增强被代理类的功能。Spring实现这一AOP功能的原理就使用代理模式(1、JDK动态代理。2、CGLib字节码生成技术代理。)对类进行方法级别的切面增强,即,生成被代理类的代理类, 并在代理类的方法前,设置拦截器,通过执行拦截器重的内容增强了代理方法的功能,实现的面向切面编程。

Adapter类接口:Target

public interface AdvisorAdapter {

boolean supportsAdvice(Advice advice);

MethodInterceptor getInterceptor(Advisor advisor);

} MethodBeforeAdviceAdapter类,Adapter

class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {

public boolean supportsAdvice(Advice advice) {

return (advice instanceof MethodBeforeAdvice);

}

public MethodInterceptor getInterceptor(Advisor advisor) {

MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();

return new MethodBeforeAdviceInterceptor(advice);

}

}

第五种:包装器(Decorator)

在我们的项目中遇到这样一个问题:我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库。我们以往在spring和hibernate框架中总是配置一个数据源,因而sessionFactory的dataSource属性总是指向这个数据源并且恒定不变,所有DAO在使用sessionFactory的时候都是通过这个数据源访问数据库。但是现在,由于项目的需要,我们的DAO在访问sessionFactory的时候都不得不在多个数据源中不断切换,问题就出现了:如何让sessionFactory在执行数据持久化的时候,根据客户的需求能够动态切换不同的数据源?我们能不能在spring的框架下通过少量修改得到解决?是否有什么设计模式可以利用呢? 

首先想到在spring的applicationContext中配置所有的dataSource。这些dataSource可能是各种不同类型的,比如不同的数据库:Oracle、SQL Server、MySQL等,也可能是不同的数据源:比如apache 提供的org.apache.commons.dbcp.BasicDataSource、spring提供的org.springframework.jndi.JndiObjectFactoryBean等。然后sessionFactory根据客户的每次请求,将dataSource属性设置成不同的数据源,以到达切换数据源的目的。

spring中用到的包装器模式在类名上有两种表现:一种是类名中含有Wrapper,另一种是类名中含有Decorator。基本上都是动态地给一个对象添加一些额外的职责。 

第六种:代理(Proxy)

为其他对象提供一种代理以控制对这个对象的访问。  从结构上来看和Decorator模式类似,但Proxy是控制,更像是一种对功能的限制,而Decorator是增加职责。 

spring的Proxy模式在aop中有体现,比如JdkDynamicAopProxy和Cglib2AopProxy。 

第七种:观察者(Observer)

定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

spring中Observer模式常用的地方是listener的实现。如ApplicationListener。 

第八种:策略(Strategy)

定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。 

spring中在实例化对象的时候用到Strategy模式

在SimpleInstantiationStrategy中有如下代码说明了策略模式的使用情况: 

第九种:模板方法(Template Method)

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

Template Method模式一般是需要继承的。这里想要探讨另一种对Template Method的理解。spring中的JdbcTemplate,在用这个类时并不想去继承这个类,因为这个类的方法太多,但是我们还是想用到JdbcTemplate已有的稳定的、公用的数据库连接,那么我们怎么办呢?我们可以把变化的东西抽出来作为一个参数传入JdbcTemplate的方法中。但是变化的东西是一段代码,而且这段代码会用到JdbcTemplate中的变量。怎么办?那我们就用回调对象吧。在这个回调对象中定义一个操纵JdbcTemplate中变量的方法,我们去实现这个方法,就把变化的东西集中到这里了。然后我们再传入这个回调对象到JdbcTemplate,从而完成了调用。这可能是Template Method不需要继承的另一种实现方式吧。

JAVA的单例模式到底有几种变现形式请列举

JAVA单例模式的几种实现方法1.饿汉式单例类package pattern.singleton;//饿汉式单例类.在类初始化时,已经自行实例化 public class Singleton1 { //私有的默认构造子 private Singleton1() {} //已经自行实例化 private static final Singleton1 single = new Singleton1(); //静态工厂方法 public static Singleton1 getInstance() { return single; }}2.懒汉式单例类package pattern.singleton;//懒汉式单例类.在第一次调用的时候实例化 public class Singleton2 { //私有的默认构造子 private Singleton2() {} //注意,这里没有final private static Singleton2 single; //只实例化一次 static{ single = new Singleton2(); } //静态工厂方法 public synchronized static Singleton2 getInstance() { if (single == null) { single = new Singleton2(); } return single; }} 在上面给出懒汉式单例类实现里对静态工厂方法使用了同步化,以处理多线程环境。有些设计师在这里建议使用所谓的“双重检查成例“.必须指出的是,“双重检查成例“不可以在Java 语言中使用。不十分熟悉的读者,可以看看后面给出的小节。 同样,由于构造子是私有的,因此,此类不能被继承。饿汉式单例类在自己被加载时就将自己实例化。即便加载器是静态的,在饿汉式单例类被加载时仍会将自己实例化。单从资源利用效率角度来讲,这个比懒汉式单例类稍差些。从速度和反应时间角度来讲,则比懒汉式单例类稍好些。然而,懒汉式单例类在实例化时,必须处 理好在多个线程同时首次引用此类时的访问限制问题,特别是当单例类作为资源控制器,在实例化时必然涉及资源初始化,而资源初始化很有可能耗费时间。这意味着出现多线程同时首次引用此类的机率变得较大。   饿汉式单例类可以在Java 语言内实现, 但不易在C++ 内实现,因为静态初始化在C++ 里没有固定的顺序,因而静态的m_instance 变量的初始化与类的加载顺序没有保证,可能会出问题。这就是为什么GoF 在提出单例类的概念时,举的例子是懒汉式的。他们的书影响之大,以致Java 语言中单例类的例子也大多是懒汉式的。实际上,本书认为饿汉式单例类更符合Java 语言本身的特点。3.登记式单例类.package pattern.singleton;import java.util.HashMap;import java.util.Map;//登记式单例类.//类似Spring里面的方法,将类名注册,下次从里面直接获取。public class Singleton3 { private static Map《String,Singleton3》 map = new HashMap《String,Singleton3》(); static{ Singleton3 single = new Singleton3(); map.put(single.getClass().getName(), single); } //保护的默认构造子 protected Singleton3(){} //静态工厂方法,返还此类惟一的实例 public static Singleton3 getInstance(String name) { if(name == null) { name = Singleton3.class.getName(); System.out.println(“name == null“+“---》name=“+name); } if(map.get(name) == null) { try { map.put(name, (Singleton3) Class.forName(name).newInstance()); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } return map.get(name); } //一个示意性的商业方法 public String about() { return “Hello, I am RegSingleton.“; } public static void main(String args) { Singleton3 single3 = Singleton3.getInstance(null); System.out.println(single3.about()); }}

如何在Java中实现单例模式

单例模式大致有五种写法,分别为懒汉,恶汉,静态内部类,枚举和双重校验锁。

1、懒汉写法,常用写法

class LazySingleton{    private static LazySingleton singleton;    private LazySingleton(){    }    public static LazySingleton getInstance(){        if(singleton==null){            singleton=new LazySingleton();        }        return singleton;    }   }

2、恶汉写法,缺点是没有达到lazy loading的效果

class HungrySingleton{    private static HungrySingleton singleton=new HungrySingleton();    private HungrySingleton(){}    public static HungrySingleton getInstance(){        return singleton;    }}

3、静态内部类,优点:加载时不会初始化静态变量INSTANCE,因为没有主动使用,达到Lazy loading

class InternalSingleton{    private static class SingletonHolder{        private final static  InternalSingleton INSTANCE=new InternalSingleton();    }       private InternalSingleton(){}    public static InternalSingleton getInstance(){        return SingletonHolder.INSTANCE;    }}

4、枚举,优点:不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象

enum EnumSingleton{    INSTANCE;    public void doSomeThing(){    }}

5、双重校验锁,在当前的内存模型中无效

class LockSingleton{    private volatile static LockSingleton singleton;    private LockSingleton(){}         //详见:

如何写一个简单的单例模式

一、基本的实现思路:

单例的实现主要是通过以下两个步骤:

1、将该类的构造方法定义为私有方法,这样其他处的代码就无法通过调用该类的构造方法来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例;

2、在该类内提供一个静态方法,当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用。

二、示范如下:

1、枚举实现单例:

2、懒汉式线程不安全:

3、懒汉式线程安全:

4、饿汉式:

5、双重校验锁:

6、静态内部类:

扩展资料:

一、单列模式简介:

单例模式是设计模式中最简单的形式之一。这一模式的目的是使得类的一个对象成为系统中的唯一实例。要实现这一点,可以从客户端对其进行实例化开始。因此需要用一种只允许生成对象类的唯一实例的机制,“阻止”所有想要生成对象的访问。使用工厂方法来限制实例化过程。这个方法应该是静态方法(类方法),因为让类的实例去生成另一个唯一实例毫无意义。

二、懒汉与饿汉:

1、懒汉方式:指全局的单例实例在第一次被使用时构建。

2、饿汉方式:指全局的单例实例在类装载时构建。

三、单例模式的三要点:

1、某个类只能有一个实例。

2、它必须自行创建这个实例。

3、它必须自行向整个系统提供这个实例。

四、优缺点:

1、优点:

①实例控制:单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例。

②灵活性:因为类控制了实例化过程,所以类可以灵活更改实例化过程。

2、缺点:

①开销:虽然数量很少,但如果每次对象请求引用时都要检查是否存在类的实例,将仍然需要一些开销。可以通过使用静态初始化解决此问题。

②可能的开发混淆:使用单例对象(尤其在类库中定义的对象)时,开发人员必须记住自己不能使用new关键字实例化对象。因为可能无法访问库源代码,因此应用程序开发人员可能会意外发现自己无法直接实例化此类。

③对象生存期:不能解决删除单个对象的问题。在提供内存管理的语言中(例如基于.NET Framework的语言),只有单例类能够导致实例被取消分配,因为它包含对该实例的私有引用。在某些语言中(如 C++),其他类可以删除对象实例,但这样会导致单例类中出现悬浮引用。

参考资料:百度百科单列模式

么是单例模式,并写出单例模式的2种实现方式

java模式之单例模式: 单例模式确保一个类只有一个实例,自行提供这个实例并向整个系统提供这个实例。 特点: 1,一个类只能有一个实例 2,自己创建这个实例 3,整个系统都要使用这个实例 Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。在很多操作中,比如建立目录 数据库连接都需要这样的单线程操作。一些资源管理器常常设计成单例模式。 外部资源:譬如每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干个通信端口,系统应当集中管理这些通信端口,以避免一个通信端口被两个请求同时调用。内部资源,譬如,大多数的软件都有一个(甚至多个)属性文件存放系统配置。这样的系统应当由一个对象来管理这些属性文件。一个例子:Windows 回收站。在整个视窗系统中,回收站只能有一个实例,整个系统都使用这个惟一的实例,而且回收站自行提供自己的实例。因此,回收站是单例模式的应用。两种形式:1,饿汉式单例类public class Singleton { private Singleton(){} //在自己内部定义自己一个实例,是不是很奇怪? //注意这是private 只供内部调用 private static Singleton instance = new Singleton(); //这里提供了一个供外部访问本class的静态方法,可以直接访问 public static Singleton getInstance() { return instance; } } 2,懒汉式单例类public class Singleton { private static Singleton instance = null; public static synchronized Singleton getInstance() { //这个方法比上面有所改进,不用每次都进行生成对象,只是第一次 //使用时生成实例,提高了效率! if (instance==null) instance=new Singleton(); return instance; } } 第二中形式是lazy initialization,也就是说第一次调用时初始Singleton,以后就不用再生成了。

JAVA单例模式的几种实现方法

单例模式1:publicclasssingleton{privatestaticsingletonst=null;privatesingleton(){}publicstaticsingletongetinstance(){if(st==null){st=newsingleton();}returnst;}}单例模式2:publicclasssingleton{privatestaticsingletonst=newsingleton();privatesingleton(){}publicstaticsingletongetinstance(){returnst;}}多线程1:导入thread所在的包publicclassmythread1extendsthread{publicvoidrun(){xxxxx写自己的代码}}多线程2导入runnable所在的包publicclassmythread2implementsrunnable{publicvoidrun(){xxxxx写自己的代码}}另写一个测试类,在main方法中这样写:threadt=newmythread1();或者runnabler=newmythread2();threadt=newthread(r);