单例模式是一种常用的软件设计模式,它所创建的对象只有一个实例,且该实例易于被外界访问。单例对象由于只有一个实例,所以它可以方便地被系统中的其他对象共享,从而减少系统中的资源开销。
双城网站制作公司哪家好,找成都创新互联公司!从网页设计、网站建设、微信开发、APP开发、响应式网站等网站项目制作,到程序开发,运营维护。成都创新互联公司公司2013年成立到现在10年的时间,我们拥有了丰富的建站经验和运维经验,来保证我们的工作的顺利进行。专注于网站建设就选成都创新互联公司。
单例模式的实现思路是:
单例模式的要点:
我们来看一下使用TypeScript实现单例模式的代码示例:
class Singleton {
// 私有静态属性,存储唯一实例
private static instance: Singleton;
// 私有构造函数,防止外部实例化
private constructor() {}
// 向外部提供能够共享访问的唯一实例
public static getInstance(): Singleton {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
// 其他方法和属性
}
const s1 = Singleton.getInstance();
const s2 = Singleton.getInstance();
console.log(s1 === s2); // true
上面代码中,Singleton类的构造函数被private修饰,使其无法在类的外部通过new来创建实例。
getInstance方法首先会判断实例是否存在,如果不存在才去新建实例,如果实例已存在则直接返回现有实例。这确保了整个程序中只会创建该类的一个实例。
测试代码中,s1和s2实际上是获取的是同一个实例对象。
图片
单例模式的优点:
单例模式的缺点:
Singleton单例:在单例类的内部实现只生成一个实例,同时提供一个静态方法getInstance()方法,让用户可以访问它的唯一实例;为了防止在外部对单例类实例化,它的构造函数可见性为private;在单例类内部定义了一个Singleton类型的静态属性instance,作为提供给外部共享访问的唯一实例。
饿汉式单例类:当类被加载时,静态属性instance会被初始化,此时类的私有构造函数会被调用,单例类的唯一实例将会被创建。
普通单例模式和饿汉式单例模式的区别:
下面我们使用TypeScript代码实现一个饿汉式单例:
class Singleton {
private static instance = new Singleton();
private constructor() {}
public static getInstance() {
return Singleton.instance;
}
}
const s1 = Singleton.getInstance();
const s2 = Singleton.getInstance();
console.log(s1 === s2); // true
饿汉式单例由于在类加载时就完成了初始化,所以理论上它是线程安全的,在多线程环境下也能保证单例。
但饿汉式也有可能造成不必要的实例化,如果这个单例的实例对象较大,而客户端又没调用getInstance方法,那就会浪费内存。
其实懒汉式单例模式,就是前面提到的普通单例模式。
懒汉式单例模式实现代码如下:
class Singleton {
private static instance: Singleton;
private constructor() {}
public static getInstance(): Singleton {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
}
但是,这种实现方式存在一个问题,就是在多线程环境下会存在安全隐患。
如果有两个线程A和B,它们同时调用 getInstance 方法,并且实例还没有被初始化,那么它们会同时执行 Singleton.instance = new Singleton();这行代码。
这样就会导致实际创建了两个实例,违反了单例模式的初衷。
为了使懒汉式单例在多线程中也是安全的,我们可以对getInstance方法加锁:
class Singleton {
private static instance: Singleton;
private constructor() {}
public static getInstance(): Singleton {
if (!Singleton.instance) {
// 加锁
lock()
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
// 释放锁
unlock()
}
return Singleton.instance;
}
}
这样当一个线程进入该方法时,其它线程就只能等待,直到锁被释放后才能进入方法。
这就确保了单例实例的唯一性。这里的锁机制可以使用互斥量mutex等各种锁的实现。
以上是关于懒汉式单例线程安全性问题的一个补充说明。让我们的单例模式实现更加健壮。
懒汉式相比饿汉式更加灵活,但需要处理多线程安全问题。饿汉式编写简单但不太高效。
在实际开发中,我们可以根据需求选择合适的实现方式,也可以采用双重校验锁等线程安全的懒汉式实现。
饿汉式单例类不能实现延迟加载,不管将来用不用,它始终占据内存;懒汉式单例类线程安全控制繁琐,而且性能收到影响。对此,无论是饿汉式单例还是懒汉式单例都在一些问题,使用IoDH(Initialization on Demand Holder)可以结合两者的优点,克服两者的缺点实现性能和实现更优的单例模式。
IoDH是一种技术方案,它利用了类的静态属性来实现延迟加载和线程安全。要实现IoDH,只需在但李磊中增加静态内部类即可,在该内部类中创建单例对象,再将该单例对象通过getInstance()方法返回给外部使用。
// 单例服务接口
interface SingletonService {
doSomething(): void;
}
// 单例服务类
class SingletonServiceImpl implements SingletonService {
doSomething() {
console.log('Doing something...');
}
}
// IoC容器类
class IoCContainer {
private singleton: SingletonService;
constructor() {
this.singleton = new SingletonServiceImpl();
}
getSingleton(): SingletonService {
return this.singleton;
}
}
// 测试代码
const container = new IoCContainer();
const s1 = container.getSingleton();
const s2 = container.getSingleton();
console.log(s1 === s2); // true
详细解析一下使用IoC容器实现单例模式的代码:
这样通过IoC容器管理单例的创建,可以实现:
单例模式作为一种设计模式,由于具有明确的目的、简单的结构和易于理解的特点,在软件开发中使用频率很高,在许多应用程序和框架中都有广泛应用。
总之,单例模式是一种利用率较高的设计模式,其限制实例个数的特点可以带来节省资源的优势,但也可能导致扩展性较弱以及与语言环境不够匹配等问题。在软件设计中,开发者需要权衡考虑系统的需求和优缺点,适当使用单例模式。
分享名称:三言两语说透设计模式的艺术-单例模式
网页链接:http://www.gawzjz.com/qtweb2/news22/3072.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联