1. 设计模式
有23个经典的设计模式
NO.1单例模式(Singleton):表示一个类只会生成唯一的一个对象。
思考:怎样可以让一个类有且只有一个实例呢?
1) 先定义两个类:
public classSingletonTest
{}
class Singleton
{}
2) 如何生成唯一的一个实例,决定于类生成实例的过程。我们知道实例生成是通过调用构造方法来实现的,而且构造方法肯定会被调用的。因此我们就考虑以构造方法为入口寻求解决方法。如果我们不提供构造方法,则系统会提供一个默认的不带参数的构造方法,每new一次,就生成一个对象,不能保证唯一性。如果我们提供构造方法,如定义一个构造方法Singleton(){},则在生成对象的时候,会调用此构造方法。如果有两个new,调用两次此构造方法,会生成两个对象,还是不能保证唯一性。
public classSingletonTest
{}
class Singleton
{
Singleton()
{}
}
3) 不提供构造方法肯定是不行的,提供了也不行,但是我们要从有构造方法这方面介入。我们知道,如果我们把构造方法定义成私有的,则外部无法调用,无法在外部生成实例,这样想感觉会少很多实例。
public classSingletonTest
{
public static void main(String[] args)
{
Singleton singleton = newSingleton();
}
}
class Singleton
{
Private Singleton()
{}
}
4) 上面程序编译错误,因为私有构造方法不能被外部调用,进而在外部new时,报错。
这样,我们就里我们的目标更近了,此时最多生成零个实例。试想,现在不能再利用new来生成实例了,因此考虑可以在类里边定义一个可以返回实例的方法,间接生成实例。
public classSingletonTest
{
public static void main(String[] args)
{
}
}
class Singleton
{
Private Singleton()
{}
public Singleton getInstance()
{
return new Singleton();
}
}
5)上面程序进入死循环,因为实例方法getInstance() 的调用必须要在外面new一个对象之后,才能用此对象调用。也就是说,在调用他之前,要先生成实例。而我们定义此方法的目的就是不用在外面new出来一个实例。因此不对。然后我们就想其他调用方法的途径,比如可以用类直接调用静态方法,因此可以把getInstance()定义为 static 的。
public classSingletonTest
{
public static void main(String[] args)
{
Singleton singleton =Singleton.getInstance();
}
}
class Singleton
{
Private Singleton()
{}
public static Singleton getInstance()
{
return new Singleton();
}
}
5) 上面程序编译通过,但是还是不能保证单例。只是把实例的生成转移到类的里面了。没调用一次,就会new一个对象。这里,我们发现,没调用一次方法getInstance()就会new 一个对象。试想,如果我们可以在方法外面先生成一个对象,然后在调用方法getInstance()的时候,返回这个生成好的对象,是不是就可以保证只有一个实例呢?
public classSingletonTest
{
public static void main(String[] args)
{
Singleton singleton =Singleton.getInstance();
}
}
class Singleton
{
private Singleton singleton = newSingleton();
private Singleton()
{}
public static Singleton getInstance()
{
return singleton;
}
}
6)此程序编译不通过,因为静态的方法只能访问静态变量。
单例模式(形式一)
*********************************************************
public classSingletonTest
{
public static void main(String[] args)
{
Singleton singleton =Singleton.getInstance();
}
}
class Singleton
{
private static Singleton singleton = newSingleton();
private Singleton()
{}
public static Singleton getInstance()
{
return singleton;
}
}
*********************************************************
6) 测试其是否真的为单例
public classSingletonTest
{
public static void main(String[] args)
{
Singleton singleton =Singleton.getInstance();
Singleton singleton1 =Singleton.getInstance();
System.out.println(singleton ==singleton1);
}
}
class Singleton
{
private static Singleton singleton = newSingleton();
private Singleton()
{}
public static Singleton getInstance()
{
return singleton;
}
}
7)
单例模式(形式二)
*********************************************************
public classSingletonTest
{
public static void main(String[] args)
{
Singleton singleton =Singleton.getInstance();
}
}
class Singleton
{
private static Singleton singleton;
private Singleton()
{}
public static Singleton getInstance()
{
If(singleton ==null){singleton = new Singleton();}
return singleton;
}
}
*********************************************************
对于前面单例模式的两种实现方法,可以先认为相同。在学习多线程之后,会知道,第二种可能不再是单例模式。因此,第一种比较优良。
第二种实现在多线程时不能保证只生成一个对象
public static Singleton getInstance()
{
If(singleton == null)
{
singleton = new Singleton();
}
return singleton;
}
分析:假设有两个线程,当第一个线程进入if循环后,正要执行:singleton= new Singleton();
他时,这时CPU将程序转到另一个线程,这时由于还没有生成对象,那么他也进入到if模块中,这样,就会生成两个对象。
异常模拟:
[com.Class013/SingletonTest2.java]
对于单例模式(Singleton)来说,如果在getInstance()方法中生成Singleton实例则可能会产生同步问题,即可能会生成两个不同的对象。
所谓设计模式(Design Pattern),是为了满足对优秀、简单而且可重用的解决方案的需要。这就像我们在盖楼的时候,我们不会每次都从零开始来画图纸,而是参照某种已有的模式,然后在此基础上来设计它。而在面向对象程序设计中,“模式”是为了实现重用面向对象代码的一种方便做法。
根据“设计模式”的经典著作《Design Patterns:Elements of reusable Object-Oriented software》中所述,设计模式一般包含四个基本要素:
1.模式名称(pattern name):一个助记名,用几个词汇来描述模式的问题、解决方案以及效果。
2.问题(problem):描述了应该在何时使用模式。
3.解决问题的方案(solution):描述了设计的组成部分,它们之间的相互关系及各自的职责和协作方式。
4.效果(consequences):描述了模式应用的效果及使用模式应权衡的问题。
我们现在来考虑单子(Singleton)设计模式的需求背景。
在实际应用中,我们可能需要限制生成的对象个数只能为1个。比如,在开发图形应用的时候,在菜单栏上按下“帮助”菜单,将弹出一个帮助对话框,也就是生成了一个帮助对话框的实例,如果对话框已经出现,则即使再在菜单栏上按下“帮助”菜单,应用程序也不应该再生成新的对话框实例。这个时候,如果还是通过原来的用构造器来生成实例的方式,很难对其生成的实例个数进行控制。通过所谓的“单子设计模式”,可以实现这个功能。
单子设计模式的基本思路是在类的内部定义一个静态变量,当创建第一个实例时设置该变量。应用程序直接使用这个静态变量指向的实例就可以了。为了防止应用程序调用构造器来新建实例,必须限制构造器的访问,也就是将它的访问控制设置为“private”。
概括起来,要实现“单子设计模式”,可以利用下面的方式来完成:
创建一个类,满足:
构造器私有;
用一个私有、静态变量引用实例;
提供一个公有、静态方法获得实例。
下面来看一个这个实现的例子:
public class SingletonPattern {
private double r;
// 定义一个私有、静态的引用变量
private static SingletonPattern sp;
// 构造器私有
private SingletonPattern() {
r = java.lang.Math.random();
}
// 提供一个公有、静态方法获得唯一实例
public static SingletonPattern getInstance() {
if (sp == null)// 如果还未创建实例
{
sp = new SingletonPattern();// 则创建一个实例
}
return sp;// 将它返回
}
public double getR() {
return r;
}
public static void main(String args[]) {
SingletonPattern sp1 = SingletonPattern.getInstance();
SingletonPattern sp2 = SingletonPattern.getInstance();
System.out.println(sp1.getR());
System.out.println(sp2.getR());
}
}
在这个例子中,我们利用上面所讨论的方法实现了“单子设计模式”,为了简单的测试我们每次得到的对象是否为同一个对象,我们在构造器中给该类的实例变量r赋了一个随机的值。如果每次得到的实例是同一个,那么,它的实例变量r的值也必定相同。
为了测试这个类,在这个类中定义了一个main()方法,然后通过SingletonPattern类的静态方法getInstance()来获得两个SingletonPattern实例,分别赋给两个引用变量sp1和sp2,然后通过这两个实例的getR()方法将它的实例变量打印出来。运行上面的程序,可以得到类似如下的输出:
0.04960654267464748
0.04960654267464748
这说明,这两个引用变量指向的是同一个实例,也就是只有一个实例存在。因为这个类的构造器被定义为“private”,所以不能直接调用它的构造器来生成新的实例,这也就避免了通过直接调用构造器生成多个实例的情况。
相关推荐
004单例模式) m) x8 z7 t( q5 P4 }4 u# v 005工厂模式+ [% H7 o% z% F7 b' N* n# {& K; _ 006命令模式9 D% c+ V8 l$ {* n, y/ N 007适配器模式 008外观模式5 d3 j: D% K3 ` t 009模板模式 010迭代器模式 011组合模式...
- 单例模式:确保一个类只有一个实例,并提供全局访问点。 - 工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。 - 抽象工厂模式:提供一个接口,用于创建相关或依赖对象的家族,而无需指定...
1. **单例模式**(Singleton):确保一个类只有一个实例,并提供全局访问点。在C++中,可以通过控制类的构造函数访问权限和提供静态成员函数来实现。001.PDF可能对此有深入的解释。 2. **工厂模式**(Factory):...
单例模式是一种常见的创建型模式,它确保一个类只有一个实例,并提供全局访问点。在.NET中,可以通过静态属性和私有构造函数来实现,或者使用System.Lazy类型来延迟初始化。 工厂模式是一种抽象的创建过程,它允许...
提供的`Android_demo_001`可能包含了如何在实际项目中使用自定义Application或单例模式的例子,你可以下载并研究这个示例来加深理解。 总的来说,通过全局对象传递数据是Android应用开发中的一种常见做法,但需要...
在多线程或并发环境下,为了保证数据的一致性和完整性,TSS并发访问方案采用了C++设计模式中的单例模式。本文将深入探讨该方案的实现原理、性能分析以及实验结果。 首先,TSS并发访问方案的核心在于单例模式。单例...
创建型模式有单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式等。例如,单例模式确保一个类只有一个实例,并提供一个全局访问点;工厂方法模式定义一个用于创建对象的接口,让子类决定实例化哪一个类。...
1. **单例模式**:确保一个类只有一个实例,并提供全局访问点。在Java中,通常通过私有构造函数和静态工厂方法来实现。 2. **工厂模式**:提供一个创建对象的接口,但让子类决定实例化哪一个类。工厂方法让类的实例...
1. 单例模式(Singleton):保证一个类只有一个实例,并提供一个全局访问点。 2. 工厂方法模式(Factory Method):定义一个用于创建对象的接口,让子类决定实例化哪一个类。 3. 抽象工厂模式(Abstract Factory):...
在多线程环境中,单例模式需要考虑线程安全问题,项目中可能有实现线程安全单例的例子。 2. **工厂模式**:提供创建对象的接口,但让子类决定实例化哪一个类。这将创建过程封装起来,使得代码更易于维护和扩展。 3...
pattern.p003.singletonEH : 单例模式(饿汉式)。 pattern.p003.singletonLH : 单例模式(懒汉式)。 pattern.p003.singletonNew : 单例模式(完美解决方案)。 pattern.p004.builder : 建造者模式。 pattern.p005....
在这个"AutofacFramework(001控制台调用Main方法通过Autofac实现的依赖注入,UnitOfWork调用模式)"的示例中,我们将看到如何在控制台应用中使用Autofac来管理依赖关系,并结合UnitOfWork模式进行数据操作。...
- **单例模式**:单例模式是一种确保类只有一个实例,并提供一个全局访问点的设计模式。 - **饿汉式**:这种实现方式在类装载时就已经创建了单例对象,因此无需担心线程安全问题。但是,由于单例对象在类装载时就...
在"2019-12-20_DICore(001控制台动态实例UnitOfWork调用模式,完成Insert、Update、Delete数据操作验证)"这个项目中,我们将看到如何在控制台应用程序中利用.NET Core的优势来执行数据库操作。 UnitOfWork模式是一...
常见的设计模式有单例模式、工厂模式、观察者模式等。在.NET Framework中,许多内置类已经实现了这些模式,比如Task类的异步操作就遵循了工厂模式。在“NoIOCFramework”中,可能涉及到了数据访问层的设计,例如使用...
3. **设计模式与框架使用**:鼓励使用已被广泛认可的设计模式,如工厂模式、单例模式等,并合理选择和使用Spring、MyBatis等框架,以保证代码的灵活性和可扩展性。 4. **异常处理**:异常处理应准确无误,避免捕获...
包的概念和使用,访问修饰符(public、private、protected和默认),理解接口和抽象类,以及如何使用设计模式(如工厂模式、单例模式)优化代码。 8. **工具** 作为标签的一部分,可能涉及到IDE(集成开发环境)...
2. **设计模式**:通过源码,我们可以学习到软件开发中的常用设计模式,如单例模式、工厂模式、观察者模式等,这些模式用于提高代码的可读性和可维护性。 3. **数据结构与算法**:源码中可能会包含各种数据结构(如...
Kotlin不仅支持面向对象编程,还支持函数式编程,而它提供的“object”关键字,是一个功能强大的语法元素,它使得开发人员可以在Kotlin中以简洁的方式实现单例模式、数据包装以及匿名内部类的功能。 首先,我们需要...
论文可能会介绍一些经典的GOF设计模式,如工厂模式、单例模式、观察者模式,并展示如何在实际编程中应用这些模式来提高代码的可读性和可维护性。 "031论数据中心集中存储架构.docx"可能涉及了数据中心的存储设计,...