GVKun编程网logo

Delphi for iOS开发指南(4):在iOS应用程序中使用不同风格的Button组件(delphi开发苹果app)

17

本文的目的是介绍Delphi实现单例模式的详细情况,特别关注SingletonPattern的相关信息。我们将通过专业的研究、有关数据的分析等多种方式,为您呈现一个全面的了解Delphi实现单例模式的

本文的目的是介绍Delphi 实现单例模式的详细情况,特别关注Singleton Pattern的相关信息。我们将通过专业的研究、有关数据的分析等多种方式,为您呈现一个全面的了解Delphi 实现单例模式的机会,同时也不会遗漏关于1.4、设计模式 [创建型]-单例模式(Singleton Pattern)、3.1 单例模式(Singleton Pattern) -《SSM深入解析与项目实战》、4、创建型-单例模式(Singleton)、C# 设计模式之一单例模式(Singleton Pattern)【创建型】的知识。

本文目录一览:

Delphi 实现单例模式(Singleton Pattern)(delphi怎么生成单独程序)

Delphi 实现单例模式(Singleton Pattern)(delphi怎么生成单独程序)

总结

以上是小编为你收集整理的Delphi 实现单例模式(Singleton Pattern)全部内容。

如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。

1.4、设计模式 [创建型]-单例模式(Singleton Pattern)

1.4、设计模式 [创建型]-单例模式(Singleton Pattern)

单例模式

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

注意:

  • 1、单例类只能有一个实例。
  • 2、单例类必须自己创建自己的唯一实例。
  • 3、单例类必须给所有其他对象提供这一实例。

介绍

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

**主要解决:**一个全局使用的类频繁地创建与销毁。

**何时使用:**当您想控制实例数目,节省系统资源的时候。

**关键代码:**构造函数是私有的。

优点:

  • 1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。
  • 2、避免对资源的多重占用(比如写文件操作)。

**缺点:**没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。

使用场景:

  • 1、要求生产唯一序列号。
  • 2、创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。

**注意事项:**getInstance() 方法中需要使用同步锁 synchronized (Singleton.class) 防止多线程同时进入造成 instance 被多次实例化。

实现

懒汉式

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

饿汉式

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

双检锁

public class Singleton {  
    private volatile static Singleton singleton;  
    private Singleton (){}  
    public static Singleton getSingleton() {  
        if (singleton == null) {  
            synchronized (Singleton.class) {  
               if (singleton == null) {  
                    singleton = new Singleton();  
                }  
            }  
        }  
        return singleton;  
    }  
}

3.1 单例模式(Singleton Pattern) -《SSM深入解析与项目实战》

3.1 单例模式(Singleton Pattern) -《SSM深入解析与项目实战》

文章目录

  • 第3章 设计模式
  • 3.1 单例模式(Singleton Pattern)
    • 3.1.1 懒汉式单例类
      • 1、先对线程不安全的实例进行演示
        • 线程不安全的懒汉式单例类
      • 线程安全的懒汉式单例类
        • 线程安全的懒汉式单例类
        • 双重检验模式
        • 静态内部类懒汉式实现
    • 3.1.2 饿汉式单例类

第3章 设计模式

设计模式在框架中的使用是很常见的。在本章,针对几个常用的设计模式进行一些介绍和深入的讲解。

3.1 单例模式(Singleton Pattern)

简单的理解单例模式,也就是一个类只能有一个实例,在项目全局中的访问都是那一个实例,确保一个单例类在全局内存中只有一个对象。

单例模式是Java中最容易理解的设计模式之一。该模式提供的是对象创建的方式,确保对象只会被创建一次,并提供唯一获取该对象的方式,并且由该类负责创建一

4、创建型-单例模式(Singleton)

4、创建型-单例模式(Singleton)

单例模式(Singleton Pattern):确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。单例模式是一种对象创建型模式。

单例模式有三个要点:

  • 1、单例类只能有一个实例。
  • 2、单例类必须自己创建自己的唯一实例。
  • 3、单例类必须给所有其他对象提供这一实例。

1.主要优点

(1) 单例模式提供了对唯一实例的受控访问。因为单例类封装了它的唯一实例,所以它可以严格控制客户怎样以及何时访问它。
(2) 由于在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象单例模式无疑可以提高系统的性能。
(3) 允许可变数目的实例。基于单例模式我们可以进行扩展,使用与单例控制相似的方法来获得指定个数的对象实例,既节省系统资源,又解决了单例对象共享过多有损性能的问题。

2.主要缺点

(1) 由于单例模式中没有抽象层,因此单例类的扩展有很大的困难。
(2) 单例类的职责过重,在一定程度上违背了“单一职责原则”。因为单例类既充当了工厂角色,提供了工厂方法,同时又充当了产品角色,包含一些业务方法,将产品的创建和产品的本身的功能融合到一起。
(3) 现在很多面向对象语言(如Java、C#)的运行环境都提供了自动垃圾回收的技术,因此,如果实例化的共享对象长时间不被利用,系统会认为它是垃圾,会自动销毁并回收资源,下次利用时又将重新实例化,这将导致共享的单例对象状态的丢失。

3.适用场景

(1) 系统只需要一个实例对象,如系统要求提供一个唯一的序列号生成器或资源管理器,或者需要考虑资源消耗太大而只允许创建一个对象。
(2) 客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例。

单例模式的几种实现方式

1、饿汉式

是否Lazy初始化:否

是否多线程安全:是

实现难度:易

描述:这种方式比较常用,但容易产生垃圾对象。 优点:没有加锁,执行效率会提高。 缺点:类加载时就初始化,浪费内存。 它基于classloader机制避免了多线程的同步问题,不过,instance在类装载时就实例化,虽然导致类装载的原因有很多种,在单例模式中大多数都是调用getInstance方法, 但是也不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化instance显然没有达到 lazy loading 的效果。

public class Singleton {  
    
    private static Singleton instance = new Singleton(); 
    
    private Singleton (){
    }  
    
    public static Singleton getInstance() {  
    	return instance;  
    }  
    
    /* 如果该对象被用于序列化,可以保证对象在序列化前后保持一致 */  
    public Object readResolve() {  
        return getInstance();  
    }
}

2、懒汉式,线程不安全

是否Lazy初始化:是

是否多线程安全:否

实现难度:易

描述:这种方式是最基本的实现方式,这种实现最大的问题就是不支持多线程。因为没有加锁 synchronized,所以严格意义上它并不算单例模式。 这种方式lazy loading很明显,不要求线程安全,在多线程不能正常工作。

public class Singleton {  
  
    /* 持有私有静态实例,防止被引用,此处赋值为null,目的是实现延迟加载 */  
    private static Singleton instance = null;  
  
    /* 私有构造方法,防止被实例化 */  
    private Singleton() {  
    }  
  
    /* 静态工程方法,创建实例 */  
    public static Singleton getInstance() {  
        if (instance == null) {  
            instance = new Singleton();  
        }  
        return instance;  
    }  
  
    /* 如果该对象被用于序列化,可以保证对象在序列化前后保持一致 */  
    public Object readResolve() {  
        return instance;  
    }  
} 

这个类可以满足基本要求,但是,像这样毫无线程安全保护的类,如果我们把它放入多线程的环境下,肯定就会出现问题了,如何解决?我们首先会想到对getInstance方法加synchronized关键字。

3、懒汉式,线程安全

是否Lazy初始化:是

是否多线程安全:是

实现难度:易

描述:这种方式具备很好的 lazy loading,能够在多线程中很好的工作,但是,效率很低,99% 情况下不需要同步。 优点:第一次调用才初始化,避免内存浪费。 缺点:必须加锁 synchronized 才能保证单例,但加锁会影响效率。

getInstance() 的性能对应用程序不是很关键(该方法使用不太频繁)。

public class Singleton {  
  
    /* 持有私有静态实例,防止被引用,此处赋值为null,目的是实现延迟加载 */  
    private static Singleton instance = null;  
  
    /* 私有构造方法,防止被实例化 */  
    private Singleton() {  
    }  
  
    /* 静态工程方法,创建实例 */  
    public static synchronized Singleton getInstance() {  
        if (instance == null) {  
            instance = new Singleton();  
        }  
        return instance;  
    } 
  
    /* 如果该对象被用于序列化,可以保证对象在序列化前后保持一致 */  
    public Object readResolve() {  
        return instance;  
    }  
}

但是,synchronized关键字锁住的是这个对象,这样的用法,在性能上会有所下降,因为每次调用getInstance(),都要对对象上锁,事实上,只有在第一次创建对象的时候需要加锁,之后就不需要了,所以,这个地方需要改进。

4、双检锁/双重校验锁

是否Lazy初始化:是

是否多线程安全:是

实现难度:较复杂

描述:这种方式采用双锁机制,安全且在多线程情况下能保持高性能。

getInstance() 的性能对应用程序很关键。

public class Singleton {  
  
    /* 持有私有静态实例,防止被引用,此处赋值为null,目的是实现延迟加载 */  
    private static Singleton instance = null;  
  
    /* 私有构造方法,防止被实例化 */  
    private Singleton() {  
    }  
  
    /* 静态工程方法,创建实例 */  
    public static Singleton getInstance() {  
        if (instance == null) {  
            synchronized (instance) {  
                if (instance == null) {  
                    instance = new Singleton();  
                }  
            }  
        }  
        return instance;  
    } 
  
    /* 如果该对象被用于序列化,可以保证对象在序列化前后保持一致 */  
    public Object readResolve() {  
        return instance;  
    }  
} 

似乎解决了之前提到的问题,将synchronized关键字加在了内部,也就是说当调用的时候是不需要加锁的,只有在instance为null,并创建对象的时候才需要加锁,性能有一定的提升。但是,这样的情况,还是有可能有问题的,看下面的情况:在Java指令中创建对象和赋值操作是分开进行的,也就是说instance = new Singleton();语句是分两步执行的。但是JVM并不保证这两个操作的先后顺序,也就是说有可能JVM会为新的Singleton实例分配空间,然后直接赋值给instance成员,然后再去初始化这个Singleton实例(指令重排序)。这样就可能出错了,我们以A、B两个线程为例:

a>A、B线程同时进入了第一个if判断

b>A首先进入synchronized块,由于instance为null,所以它执行instance = new Singleton();

c>由于JVM内部的优化机制,JVM先画出了一些分配给Singleton实例的空白内存,并赋值给instance成员(注意此时JVM没有开始初始化这个实例),然后A离开了synchronized块。

d>B进入synchronized块,由于instance此时不是null,因此它马上离开了synchronized块并将结果返回给调用该方法的程序。

e>此时B线程打算使用Singleton实例,却发现它没有被初始化,于是错误发生了。

所以程序还是有可能发生错误,其实程序在运行过程是很复杂的,从这点我们就可以看出,尤其是在写多线程环境下的程序更有难度,有挑战性。我们对该程序做进一步优化。实际情况是,单例模式使用内部类来维护单例的实现,JVM内部的机制能够保证当一个类被加载的时候,这个类的加载过程是线程互斥的。这样当我们第一次调用getInstance的时候,JVM能够帮我们保证instance只被创建一次,并且会保证把赋值给instance的内存初始化完毕,这样我们就不用担心上面的问题。同时该方法也只会在第一次调用的时候使用互斥机制,这样就解决了低性能问题。这样我们暂时总结一个完美的单例模式。

5、登记式/静态内部类

是否Lazy初始化:是

是否多线程安全:是

实现难度:一般

描述:这种方式能达到双检锁方式一样的功效,但实现更简单。对静态域使用延迟初始化,应使用这种方式而不是双检锁方式。这种方式只适用于静态域的情况,双检锁方式可在实例域需要延迟初始化时使用。 这种方式同样利用了 classloader 机制来保证初始化 instance 时只有一个线程,它跟第 1 种方式不同的是:第 1 种方式只要 Singleton 类被装载了,那么 instance 就会被实例化(没有达到 lazy loading 效果),而这种方式是 Singleton 类被装载了,instance 不一定被初始化。因为 SingletonFactory类没有被主动使用,只有通过显式调用 getInstance 方法时,才会显式装载 SingletonFactory类,从而实例化 instance。想象一下,如果实例化 instance 很消耗资源,所以想让它延迟加载,另外一方面,又不希望在 Singleton 类加载时就实例化,因为不能确保 Singleton 类还可能在其他的地方被主动使用从而被加载,那么这个时候实例化 instance 显然是不合适的。这个时候,这种方式相比第 1 种方式就显得很合理。

public class Singleton {  
  
    /* 私有构造方法,防止被实例化 */  
    private Singleton() {  
    }  
  
    /* 此处使用一个内部类来维护单例 */  
    private static class SingletonFactory {  
        private static Singleton instance = new Singleton();  
    }  
  
    /* 获取实例 */  
    public static Singleton getInstance() {  
        return SingletonFactory.instance;  
    }  
  
    /* 如果该对象被用于序列化,可以保证对象在序列化前后保持一致 */  
    public Object readResolve() {  
        return getInstance();  
    }  
} 

其实说它完美,也不一定,如果在构造函数中抛出异常,实例将永远得不到创建,也会出错。所以说,十分完美的东西是没有的,我们只能根据实际情况,选择最适合自己应用场景的实现方法。也有人这样实现:因为我们只需要在创建类的时候进行同步,所以只要将创建和getInstance()分开,单独为创建加synchronized关键字,也是可以的:

public class SingletonTest {  
  
    private static SingletonTest instance = null;  
  
    private SingletonTest() {  
    }  
  
    private static synchronized void syncInit() {  
        if (instance == null) {  
            instance = new SingletonTest();  
        }  
    }  
  
    public static SingletonTest getInstance() {  
        if (instance == null) {  
            syncInit();  
        }  
        return instance;  
    }  
    
    /* 如果该对象被用于序列化,可以保证对象在序列化前后保持一致 */  
    public Object readResolve() {  
        return getInstance();  
    }
} 

考虑性能的话,整个程序只需创建一次实例,所以性能也不会有什么影响。

6、枚举

是否Lazy初始化:否

是否多线程安全:是

实现难度:易

描述:这种实现方式还没有被广泛采用,但这是实现单例模式的最佳方法。它更简洁,自动支持序列化机制,绝对防止多次实例化。 这种方式是 Effective Java 作者 Josh Bloch 提倡的方式,它不仅能避免多线程同步问题,而且还自动支持序列化机制,防止反序列化重新创建新的对象,绝对防止多次实例化。不过,由于 JDK1.5 之后才加入 enum 特性,用这种方式写不免让人感觉生疏,在实际工作中,也很少用。 不能通过 reflection attack 来调用私有构造方法。

public enum Singleton {  
    INSTANCE;  
    public void whateverMethod() {  
    }  
}

经验之谈:一般情况下,不建议使用第 2 种和第 3 种懒汉方式,建议使用第 1 种饿汉方式。只有在要明确实现 lazy loading 效果时,才会使用第 5 种登记方式。如果涉及到反序列化创建对象时,可以尝试使用第 6 种枚举方式。如果有其他特殊的需求,可以考虑使用第 4 种双检锁方式。

补充:采用"影子实例"的办法为单例对象的属性同步更新。采用"影子实例"的办法具体说,就是在更新属性时,直接生成另一个单例对象实例,这个新生成的单例对象实例将从数据库或文件中读取最新的配置信息;然后将这些配置信息直接赋值给旧单例对象的属性。
public class SingletonTest {  
  
    private static SingletonTest instance = null;  
    private Vector properties = null;  
  
    public Vector getProperties() {  
        return properties;  
    }  
  
    private SingletonTest() {  
    }  
  
    private static synchronized void syncInit() {  
        if (instance == null) {  
            instance = new SingletonTest();  
        }  
    }  
  
    public static SingletonTest getInstance() {  
        if (instance == null) {  
            syncInit();  
        }  
        return instance;  
    }  
  
    public void updateProperties() {  
        SingletonTest shadow = new SingletonTest();  
        properties = shadow.getProperties();  
    }  
}

通过单例模式的学习告诉我们:

1、单例模式理解起来简单,但是具体实现起来还是有一定的难度。

2、synchronized关键字锁定的是对象,在用的时候,一定要在恰当的地方使用(注意需要使用锁的对象和过程,可能有的时候并不是整个对象及整个过程都需要锁)。

采用类的静态方法,实现单例模式的效果,也是可行的,此处二者有什么不同?

首先,静态类不能实现接口。(从类的角度说是可以的,但是那样就破坏了静态了。因为接口中不允许有static修饰的方法,所以即使实现了也是非静态的)

其次,单例可以被延迟初始化,静态类一般在第一次加载是初始化。之所以延迟加载,是因为有些类比较庞大,所以延迟加载有助于提升性能。

再次,单例类可以被继承,他的方法可以被覆写。但是静态类内部方法都是static,无法被覆写。

最后一点,单例类比较灵活,毕竟从实现上只是一个普通的Java类,只要满足单例的基本需求,你可以在里面随心所欲的实现一些其它功能,但是静态类不行。从上面这些概括中,基本可以看出二者的区别,但是,从另一方面讲,我们上面最后实现的那个单例模式,内部就是用一个静态类来实现的,所以,二者有很大的关联,只是我们考虑问题的层面不同罢了。两种思想的结合,才能造就出完美的解决方案,就像HashMap采用数组+链表来实现一样,其实生活中很多事情都是这样,单用不同的方法来处理问题,总是有优点也有缺点,最完美的方法是,结合各个方法的优点,才能最好的解决问题!

C# 设计模式之一单例模式(Singleton Pattern)【创建型】

C# 设计模式之一单例模式(Singleton Pattern)【创建型】

一、引言

     看了李建忠老师的讲的设计模式已经有一段时间了(这段时间大概有一年多了),自己还没有写过自己的、有关设计模式的文章。这次想写一些关于设计模式的文章,用自己的理解和代码来写,算是复习一遍。写作的过程中也会多看看其他大牛的文章,争取让自己的理解正确,否则把大家带跑偏了,就是我的过错了。今天就开始我们第一个设计模式,该模式是:【单例模式】,英文名称:Singleton Pattern,这个模式很简单,一个类型只需要一个实例,他是创建型的设计模式。为什么叫 “创建型” 设计模式呢,因为他们有分类。当然了分类的方式不一样,分类的结果也就不一样。

    从目的来看:

       - 创建型(Creational)模式:负责对象创建

       - 结构型(Structural)模式:处理类与对象间的组合

       - 行为型(Behavioral)模式:类与对象交互中的职责分配

   从范围来看:

      - 类模式处理类与子类的静态关系

      - 对象模式处理对象间的动态关系

  以上就是分类的方式,我们按大多数的分类,采用 “从目的来看” 的分类来对设计模式进行分类,我们就开始今天的学习吧。

二、单例模式的介绍

   2.1、动机(Motivate)

          在软件系统中,经常有这样一些特殊的类,必须保证它们在系统中只存在一个实例,才能确保它们的逻辑正确性、以及良好的效率。

     如何绕过常规的构造器,提供一种机制来保证一个类只有一个实例?

         这应该是类设计者的责任,而不是使用者的责任

   2.2、意图(Intent)

         保证一个类仅有一个实例,并提供一个该实例的全局访问点。                                   --《设计模式 GoF》

   2.3、结构图(Structure)

      

  2.4、模式的组成

         (1)、单件实例(Singleton):这个模式里面只有一个类型,就是 Singleton 类型,并且这个类只有一个实例,可以通过 Instance () 方法获取该类型的实例。

  2.5、单件模式的代码实现

         既然是单实例,肯定会涉及到多线程的问题,我们就一步一步的来写代码,我们先看看单线程 Singleton 模式的实现,代码如下:

 1 /// <summary>
 2 /// 单例模式的实现  3 /// </summary>  4 public sealed class Singleton  5 {  6 // 定义一个静态变量来保存类的实例  7 private static Singleton uniqueInstance;  8  9 // 定义私有构造函数,使外界不能创建该类实例 10 private Singleton() 11  { 12  } 13 14 /// <summary> 15 /// 定义公有方法提供一个全局访问点,同时你也可以定义公有属性来提供全局访问点 16 /// </summary> 17 /// <returns></returns> 18 public static Singleton GetInstance() 19  { 20 // 如果类的实例不存在则创建,否则直接返回 21 if (uniqueInstance == null) 22  { 23 uniqueInstance = new Singleton(); 24  } 25 return uniqueInstance; 26  } 27 }


    私有的实例构造器是屏蔽外界的调用,上面的单例模式的实现在单线程下确实是完美的,也很好的满足了我们单线程环境的需求。

    单线程单例模式的几个要点:

    (1)、Singleton 模式中的实例构造器可以设置为 protected 以允许子类派生。

    (2)、Singleton 模式一般不要支持 ICloneable 接口,因为这可能会导致多个对象实例,与 Singleton 模式的初衷违背。

    (3)、Singleton 模式一般不要支持序列化,因为这也有可能导致多个对象实例,同样与 Singleton 模式的初衷违背。

    (4)、Singletom 模式只考虑到了对象创建的工作,没有考虑对象销毁的工作。为什么这样做呢,因为 Net 平台是支持垃圾回收的,所以我们一般没有必要对其进行销毁处理。

    (5)、不能应对多线程环境:在多线程环境下,使用 Singleton 模式仍然有可能得到 Singleton 类的多个实例对象


    如果放在多线程环境下,问题就出来了。因为在两个线程同时运行 GetInstance 方法时,此时两个线程判断 (uniqueInstance ==null) 这个条件时都返回真,此时两个线程就都会创建 Singleton 的实例,这样就违背了我们单例模式初衷了。要想解决这个问题,只要让 GetInstance 方法在同一时间只运行一个线程运行就好了,让我们看看多线程 Singleton 模式的实现,代码如下:

 1     /// <summary>
 2     /// 单例模式的实现  3 /// </summary>  4 public sealed class Singleton  5  {  6 // 定义一个静态变量来保存类的实例  7 private static volatile Singleton uniqueInstance;  8  9 // 定义一个标识确保线程同步 10 private static readonly object locker = new object(); 11 12 // 定义私有构造函数,使外界不能创建该类实例 13 private Singleton() 14  { 15  } 16 17 /// <summary> 18 /// 定义公有方法提供一个全局访问点,同时你也可以定义公有属性来提供全局访问点 19 /// </summary> 20 /// <returns></returns> 21 public static Singleton GetInstance() 22  { 23 // 当第一个线程运行到这里时,此时会对locker对象 "加锁" 24 // 当第二个线程运行该方法时,首先检测到locker对象为"加锁"状态,该线程就会挂起等待第一个线程解锁 25 // lock语句运行完之后(即线程运行完之后)会对该对象"解锁" 26 lock (locker) 27  { 28 // 如果类的实例不存在则创建,否则直接返回 29 if (uniqueInstance == null) 30  { 31 uniqueInstance = new Singleton(); 32  } 33  } 34 35 return uniqueInstance; 36  } 37 }

    上面这种解决方案确实可以解决多线程的问题,但是上面代码对于每个线程都会对线程辅助对象 locker 加锁之后再判断实例是否存在,对于这个操作完全没有必要的,因为当第一个线程创建了该类的实例之后,后面的线程此时只需要直接判断(uniqueInstance==null)为假,此时完全没必要对线程辅助对象加锁之后再去判断,所以上面的实现方式增加了额外的开销,损失了性能,为了改进上面实现方式的缺陷,我们只需要在 lock 语句前面加一句(uniqueInstance==null)的判断就可以避免锁所增加的额外开销,这种实现方式我们就叫它 “双重锁定(Double Check)”,下面具体看看实现代码的:

 1     /// <summary>
 2     /// 单例模式的实现  3 /// </summary>  4 public sealed class Singleton  5  {  6 // 定义一个静态变量来保存类的实例  7 private static volatile Singleton uniqueInstance;  8  9 // 定义一个标识确保线程同步 10 private static readonly object locker = new object(); 11 12 // 定义私有构造函数,使外界不能创建该类实例 13 private Singleton() 14  { 15  } 16 17 /// <summary> 18 /// 定义公有方法提供一个全局访问点,同时你也可以定义公有属性来提供全局访问点 19 /// </summary> 20 /// <returns></returns> 21 public static Singleton GetInstance() 22  { 23 // 当第一个线程运行到这里时,此时会对locker对象 "加锁" 24 // 当第二个线程运行该方法时,首先检测到locker对象为"加锁"状态,该线程就会挂起等待第一个线程解锁 25 // lock语句运行完之后(即线程运行完之后)会对该对象"解锁" 26 // 双重锁定只需要一句判断就可以了 27 if (uniqueInstance == null) 28  { 29 lock (locker) 30  { 31 // 如果类的实例不存在则创建,否则直接返回 32 if (uniqueInstance == null) 33  { 34 uniqueInstance = new Singleton(); 35  } 36  } 37  } 38 return uniqueInstance; 39  } 40 }

        volatile 修饰:编译器在编译代码的时候会对代码的顺序进行微调,用 volatile 修饰保证了严格意义的顺序。一个定义为 volatile 的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。

三、C# 中实现了单例模式的类

    现在我们看看,如何使用 C# 语言的特性来实现单例的 Singleton 模式。

//Singleton模式的实现
public sealed class Singleton { public static readonly Singleton instance=new Singleton(); private Singleton(){} } 以上是内联初始化(生成的同时进行初始化)的单例模式,它等同于: public sealed class Singleton { public static readonly Singleton instance; //静态构造函数,CLR只执行一次 static Singleton() { instance=new Singleton(); } //私有构造函数,防止外界调用 private Singleton(){} }

    内联初始化其实是把静态的字段放到静态构造器去初始化。只要想访问静态字段,必定已经在之前执行了静态构造器。这样也能够精确地保证使用的时候一定能拿到实例,如果不使用也不会实例化对象,也就是延时加载的功能。他同样能够支持多线程环境,因为只可能有一个线程执行静态构造器,不可能有多个线程去执行静态构造器,感觉就是程序已经自动为我们加锁了。

     它的一点弊端就是它不支持参数化的实例化方法。在.NET 里静态构造器只能声明一个,而且必须是无参数的,私有的。因此这种方式只适用于无参数的构造器。

     需要说明的是:HttpContext.Current 就是一个单例,他们是通过 Singleton 的扩展方式实现的,他们的单例也并不是覆盖所有领域,只是针对某些局部领域中,是单例的,不同的领域中还是会有不同的实例。

四、Singleton 模式的扩展

     (1)、将一个实例扩展到 n 个实例,例如对象池的实现。(n 不是指无限个实例,而是固定的某个数)

     (2)、将 new 构造器的调用转移到其他类中,例如多个类协同工作环境中,某个局部环境只需要拥有某个类的一个实例。

     (3)、理解和扩展 Singleton 模式的核心是 “如何控制用户使用 new 对一个类的实例构造器的任意调用”。

五、单例模式的实现要点

      1、Singleton 模式是限制而不是改进类的创建。

      2、Singleton 类中的实例构造器可以设置为 Protected 以允许子类派生。

      3、Singleton 模式一般不要支持 Icloneable 接口,因为这可能导致多个对象实例,与 Singleton 模式的初衷违背。

      4、Singleton 模式一般不要支持序列化,这也有可能导致多个对象实例,这也与 Singleton 模式的初衷违背。

      5、Singleton 只考虑了对象创建的管理,没有考虑到销毁的管理,就支持垃圾回收的平台和对象的开销来讲,我们一般没必要对其销毁进行特殊的管理。

      6、理解和扩展 Singleton 模式的核心是 “如何控制用户使用 new 对一个类的构造器的任意调用”。

      7、可以很简单的修改一个 Singleton,使它有少数几个实例,这样做是允许的而且是有意义的。

       1】、单例模式的优点:

             (1)、实例控制:Singleton 会阻止其他对象实例化其自己的 Singleton 对象的副本,从而确保所有对象都访问唯一实例

             (2)、灵活性:因为类控制了实例化过程,所以类可以更加灵活修改实例化过程

        2】、单例模式的缺点:

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

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

             (3)、对象的生存期:Singleton 不能解决删除单个对象的问题。因为它包含对该静态的私有字段的引用,静态字段是不能被 CLR 回收内存的,该实例会和应用程序生命周期一样长,一直存在。

       3】、单例模式的使用场合:

            (1)、当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。

            (2)、当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。

六、总结

    到这里,单例模式就介绍完了,这个模式很简单,理解起来也不是很难,只要把握住代码的实现技巧,一般问题都不大,但是要找好使用的时机,如果使用错误,一些逻辑错误比较难排查。

今天关于Delphi 实现单例模式Singleton Pattern的分享就到这里,希望大家有所收获,若想了解更多关于1.4、设计模式 [创建型]-单例模式(Singleton Pattern)、3.1 单例模式(Singleton Pattern) -《SSM深入解析与项目实战》、4、创建型-单例模式(Singleton)、C# 设计模式之一单例模式(Singleton Pattern)【创建型】等相关知识,可以在本站进行查询。

本文的目的是介绍DELPHI XE4 让AlphaControls8.52改变DevExpress13.1.4皮肤的详细情况,特别关注delphi exe 修改的相关信息。我们将通过专业的研究、有关数据的分析等多种方式,为您呈现一个全面的了解DELPHI XE4 让AlphaControls8.52改变DevExpress13.1.4皮肤的机会,同时也不会遗漏关于.Delphi7升级到Delphi 2010、Delphi XE、Delphi XE2总结、Alpha Controls for Delphi、c# devExpress控件 comboBoxEdit,gridControl1,labelcontrol、xtraReports、Delphi 10 Seattle 编译DevExpress VCl 14.x版本源码的问题的知识。

本文目录一览:

DELPHI XE4 让AlphaControls8.52改变DevExpress13.1.4皮肤(delphi exe 修改)

DELPHI XE4 让AlphaControls8.52改变DevExpress13.1.4皮肤(delphi exe 修改)

总结

以上是小编为你收集整理的DELPHI XE4 让AlphaControls8.52改变DevExpress13.1.4皮肤全部内容。

如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。

.Delphi7升级到Delphi 2010、Delphi XE、Delphi XE2总结

.Delphi7升级到Delphi 2010、Delphi XE、Delphi XE2总结

总结

以上是小编为你收集整理的.Delphi7升级到Delphi 2010、Delphi XE、Delphi XE2总结全部内容。

如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。

Alpha Controls for Delphi

Alpha Controls for Delphi

总结

以上是小编为你收集整理的Alpha Controls for Delphi全部内容。

如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。

c# devExpress控件 comboBoxEdit,gridControl1,labelcontrol、xtraReports

c# devExpress控件 comboBoxEdit,gridControl1,labelcontrol、xtraReports

一、comboBoxEdit:下拉框

属性

添加项:Properties->items

二、gridControl

C# DevExpress控件Gridview和GridControl学习总结

gridControl与Gridview的区别:前者是容器,后者为视图

2)gridView

属性

this.gridView.IsEmpty:判断gridview是否有行数据。

事件

FocusedRowChanged:行选择焦点变化时发生的事件 ,可用于两个gridview查询关联等。

RowCellStyle:改变行颜色

private void gridViewMain_RowCellStyle(object sender, DevExpress.XtraGrid.Views.Grid.RowCellStyleEventArgs e)
{
  DevExpress.XtraGrid.Views.Grid.GridView view = sender as DevExpress.XtraGrid.Views.Grid.GridView;
  if (e.RowHandle >= 0)
  {
    string category = view.GetRowCellDisplayText(e.RowHandle, view.Columns["FEEDBACK"]);
    if (category == "未确认接收")
    {
      e.Appearance.BackColor = Color.Firebrick;//设置行颜色
      e.Appearance.BackColor2 = Color.Firebrick;//设置行底色颜色
      e.Appearance.ForeColor = Color.White;//字体颜色
    }
  }
}

 

 与DataTable关联

DataTable dtSelect = (DataTable)this.ucGrid_main.DataSource;//获取ucGrid_main数据源,DataTable 是显示界面ucGrid_main上已查询的数据,不是数据库的数据

3)DevExpress GridView 自定义行高

//设置GridView行高
        private void gridView1_CalcRowHeight(object sender, DevExpress.XtraGrid.Views.Grid.RowHeightEventArgs e)
        {
            if (e.RowHandle >= 0)
                e.RowHeight = 35;

--------------------- 
作者:呼噜噜哟 
来源:CSDN 
原文:https://blog.csdn.net/u011176794/article/details/79894198 
版权声明:本文为博主原创文章,转载请附上博文链接!

 

设置隔行默认颜色

grdMain.OptionsView.EnableAppearanceEvenRow = true;
grdMain.OptionsView.EnableAppearanceOddRow = true;

 

 

 

DevExpress GridView控件设置默认选中的行颜色

 

C# DataGridView控件清空数据完美解决方法

 想要满足保持原有的列,就是重新绑定之前的DataTable,然后清除DataTable中的数据,如下:

DataTable  dt =  (DataTable)dataGridView1.DataSource;
dt.Rows.Clear();
dataGridView1.DataSource  =  dt;

 

获取或设置是否可以合并具有相同值的相邻单元格当前的列。 

this.gridView1.Columns["字段"].OptionsColumn.AllowMerge = DevExpress.Utils.DefaultBoolean.True;
this.gridView1.Columns["字段"].OptionsColumn.AllowMerge = DevExpress.Utils.DefaultBoolean.True;

 

DevExpress.XtraGrid添加Button列

 

【DevExpress】GridControl添加按钮列并添加按钮事件

 

在GridControl中添加按钮列的步骤如下: 

1. 把列的ColumnEdit属性设置为RepositoryItemButtonEdit 

2. 把TextEditStyle属性设置为HideTextEditor;

3. 把Buttons的Kind属性设置为Glyph; 

4. 把Buttons的HorzAlignment属性设置为Near; 

5. 如果要用到事件的话,还要注册事件:

(1)手动注册:

this.repositoryItemButtonEdit1.ButtonClick += new DevExpress.XtraEditors.Controls.ButtonPressedEventHandler(this.repositoryItemButtonEdit1
ButtonClick);

(2)系统自动生成事件:

 在GridControl的设计器中Repository页中的In-place Editor Repository项中在右边的Repository栏中找到你的ButtonEdit,选它的事件属性页,注册它的ButtonClick事件即可.

三、labelcontrol 标题标签

LabelControl文本居中显示:

先设置AutoSizeMode为None,然后设置LabelControl.Appearance.TextOptions.HAlignment属性为Center

 

DevExpress GridControl 按扭列的操作

 

 滚动条样式

不想自己做只能用自带的几种样式了。
LookAndFeel的UseDefaultLookAndFeel设置为false,然后SkinName选择想要的样式即可。

xtraReports

 

 

Delphi 10 Seattle 编译DevExpress VCl 14.x版本源码的问题

Delphi 10 Seattle 编译DevExpress VCl 14.x版本源码的问题

总结

以上是小编为你收集整理的Delphi 10 Seattle 编译DevExpress VCl 14.x版本源码的问题全部内容。

如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。

今天关于DELPHI XE4 让AlphaControls8.52改变DevExpress13.1.4皮肤delphi exe 修改的介绍到此结束,谢谢您的阅读,有关.Delphi7升级到Delphi 2010、Delphi XE、Delphi XE2总结、Alpha Controls for Delphi、c# devExpress控件 comboBoxEdit,gridControl1,labelcontrol、xtraReports、Delphi 10 Seattle 编译DevExpress VCl 14.x版本源码的问题等更多相关知识的信息可以在本站进行查询。

最近很多小伙伴都在问Delphi for iOS开发指南(4):在iOS应用程序中使用不同风格的Button组件delphi开发苹果app这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展AXWireButton iOS 线框风格的 UIButton、Delphi Firemonkey iOS应用程序中是否提供多点触控手势编程?、Delphi for iOS开发指南(1):在Mac上配置你的开发环境、Delphi for iOS开发指南(10): 在iOS应用程序中使用Layout来调整窗体尺寸或排列方向等相关知识,下面开始了哦!

本文目录一览:

Delphi for iOS开发指南(4):在iOS应用程序中使用不同风格的Button组件(delphi开发苹果app)

Delphi for iOS开发指南(4):在iOS应用程序中使用不同风格的Button组件(delphi开发苹果app)

总结

以上是小编为你收集整理的Delphi for iOS开发指南(4):在iOS应用程序中使用不同风格的Button组件全部内容。

如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。

AXWireButton iOS 线框风格的 UIButton

AXWireButton iOS 线框风格的 UIButton

AXWireButton 介绍

AXWireButton 是线或者边界风格的 UIButton,是 iOS 7 很好的平滑设计。

AXWireButton 官网

https://github.com/akiroom/AXWireButton#

Delphi Firemonkey iOS应用程序中是否提供多点触控手势编程?

Delphi Firemonkey iOS应用程序中是否提供多点触控手势编程?

我有兴趣使用Delphi XE2来制作iOS应用程序.目前是否支持使用Firemonkey进行多点触控(2-3次手指滑动)?如果是,是否有一些参考或样品可用?

解决方法

不,Firemonkey for iOS尚未提供多点触控和手势功能.

但是:你可以解决它,比如Anders Ohlsson showed.他在Embarcadero CodeCentral上制作了modifications to Firemonkey available.

Delphi for iOS开发指南(1):在Mac上配置你的开发环境

Delphi for iOS开发指南(1):在Mac上配置你的开发环境

总结

以上是小编为你收集整理的Delphi for iOS开发指南(1):在Mac上配置你的开发环境全部内容。

如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。

Delphi for iOS开发指南(10): 在iOS应用程序中使用Layout来调整窗体尺寸或排列方向

Delphi for iOS开发指南(10): 在iOS应用程序中使用Layout来调整窗体尺寸或排列方向

总结

以上是小编为你收集整理的Delphi for iOS开发指南(10): 在iOS应用程序中使用Layout来调整窗体尺寸或排列方向全部内容。

如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。

关于Delphi for iOS开发指南(4):在iOS应用程序中使用不同风格的Button组件delphi开发苹果app的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于AXWireButton iOS 线框风格的 UIButton、Delphi Firemonkey iOS应用程序中是否提供多点触控手势编程?、Delphi for iOS开发指南(1):在Mac上配置你的开发环境、Delphi for iOS开发指南(10): 在iOS应用程序中使用Layout来调整窗体尺寸或排列方向等相关内容,可以在本站寻找。

本文标签: