第二章 单例模式练习

合集下载

python实现单例模式的5种方法

python实现单例模式的5种方法

python实现单例模式的5种⽅法⼀、classmethod装饰器# 全局变量ip = '192.168.13.98'port = '3306'class MySQL:__instance = Nonedef __init__(self, ip, port):self.ip = ipself.port = port@classmethoddef instance(cls, *args, **kwargs):if args or kwargs:cls.__instance = cls(*args, **kwargs)return cls.__instanceobj1 = MySQL.instance(ip, port)obj2 = MySQL.instance()obj3 = MySQL.instance()print(obj1)print(obj2, obj2.__dict__)print(obj3, obj3.__dict__)输出结果<main.MySQL object at 0x058D6F30><main.MySQL object at 0x058D6F30> {'ip': '192.168.13.98', 'port': '3306'}<main.MySQL object at 0x058D6F30> {'ip': '192.168.13.98', 'port': '3306'}⼆、类的装饰器def singlegon(cls):_instance = cls(ip, port)def wrapper(*args, **kwargs):if args or kwargs:return cls(*args, **kwargs)return _instancereturn wrapper@singlegonclass MySQL1:def __init__(self, ip, port):self.ip = ipself.port = portobj1 = MySQL1()obj2 = MySQL1()obj3 = MySQL1('1.1.1.3', 8080)print(obj1)print(obj2, obj2.__dict__)print(obj3, obj3.__dict__)运⾏结果<main.MySQL1 object at 0x04C102B0><main.MySQL1 object at 0x04C102B0> {'ip': '192.168.13.98', 'port': '3306'}<main.MySQL1 object at 0x04C10310> {'ip': '1.1.1.3', 'port': 8080}三、元类class Mymetaclass(type):def __init__(self, class_name, class_bases, class_dic):super().__init__(class_name, class_bases, class_dic)self.__instance = self(ip, port)def __call__(self, *args, **kwargs):if args or kwargs:obj = self.__new__(self)self.__init__(obj, *args, **kwargs)self.__instance = objreturn self.__instanceclass MySQL2(metaclass=Mymetaclass):def __init__(self, ip, port):self.ip = ipself.port = portobj1 = MySQL2()obj2 = MySQL2()obj3 = MySQL2('1.1.1.3', 80)print(obj1)print(obj2, obj2.__dict__)print(obj3, obj3.__dict__)运⾏结果<main.MySQL2 object at 0x04D003B0><main.MySQL2 object at 0x04D003B0> {'ip': '192.168.13.98', 'port': '3306'}<main.MySQL2 object at 0x04D003D0> {'ip': '1.1.1.3', 'port': 80}四、模块导⼊# instance.pyclass MySQL:def __init__(self, ip, port):self.ip = ipself.port = portip = '192.168.13.98'port = 3306instance = MySQL(ip, port)# 测试代码import os, syssys.path.append(os.path.dirname(os.path.dirname(__file__)))from test import instanceobj1 = instance.instanceobj2 = instance.instanceobj3 = instance.MySQL('1.1.1.3', 80)print(obj1)print(obj2, obj2.__dict__)print(obj3, obj3.__dict__)运⾏结果<day30.instance.MySQL object at 0x052B0AB0><day30.instance.MySQL object at 0x052B0AB0> {'ip': '192.168.13.98', 'port': 3306} <day30.instance.MySQL object at 0x052B03F0> {'ip': '1.1.1.3', 'port': 80}五、重写__new__()class MySQL3(object):__instance = None__first_init = Truedef __init__(self, ip, port):if self.__first_init:self.ip = ipself.port = portself.__first_init = Falsedef __new__(cls, *args, **kwargs):if not cls.__instance:cls.__instance = object.__new__(cls)return cls.__instanceobj1 = MySQL3(ip, port)obj2 = MySQL3(ip, port)obj3 = MySQL3('1.1.1.3', 80)print(obj1)print(obj2, obj2.__dict__)print(obj3, obj3.__dict__)运⾏结果<main.MySQL3 object at 0x059603F0><main.MySQL3 object at 0x059603F0> {'ip': '192.168.13.98', 'port': '3306', '_MySQL3__first_init': False}<main.MySQL3 object at 0x059603F0> {'ip': '192.168.13.98', 'port': '3306', '_MySQL3__first_init': False}注:前四种可以实现单例模式,但都不是绝对单例模式,可以创建新的对象,但是第五种⽅式是绝对单例模式,全局只能真正创建⼀次对象以上就是python 实现单例模式的5种⽅法的详细内容,更多关于python 单例模式的资料请关注其它相关⽂章!。

23 单例模式及31 组合模式作业答案

23 单例模式及31 组合模式作业答案

2.3 单例模式
1、使用单例模式设计一个随机数产生器,整个应用程序中只需要一个类的实例来产生随机数,客户端程序从类中获取这个实例,调用这个实例的方法setSeed()设置起始数以及nextInt()随机产生下一个数。

要求画出类图。

2、使用单例模式设计一个打印机管理软件,每台计算机可以有若干个打印机,但只能有一个Printer Spooler,以避免两个打印作业同时输出到打印机中。

客户端从类中获取Printer Spooler的实例,调用这个实例的方法printJob(File job)打印作业。

要求画出类图。

3.1 组合模式
3、使用组合模式设计一个杀毒软件(AntiVirus)的框架,该软件既可以对某个文件夹(Folder)杀毒,也可以对某个指定的文件(File)进行杀毒,文件种类包括文本文件TextFile、图片文件ImageFile、视频文件VideoFile。

请画出类图。

答案:
AbstractFile充当抽象构件类,Folder充当容器构件类,ImageFile、TextFile和VideoFile充当叶子构件类
4、如图所示是某公司的组织结构图,现采用组合设计模式来设计,请画出类图。

答案:
其中Company为抽象类,定义了在组织结构图上添加(Add)和删除(Delete)分公司/办事处或者部门的方法接口。

类ConcreteCompany表示具体的分公司或者办事处,分公司或办事处下可以设置不同的部门。

类HRDepartment和FinanceDepartment分别表示人力资源部和财
务部。

Java中的单例模式详解(完整篇)

Java中的单例模式详解(完整篇)

Java中的单例模式详解(完整篇)⽬录前⾔WHATWHY饿汉式实现⼀:静态实例参数与静态代码块实现⼆:静态内部类懒汉式错误⼀:单线程实现错误⼆:同步⽅法错误三:同步代码块之单次检查错误四:同步代码块之双重检查正确:双重检查+阻⽌重排序枚举场景总结前⾔个⼈认为单例模式是设计模式中最简单也是最常⽤的⼀种,是对有限资源合理利⽤的⼀种⽅式。

这个模式看似简单,但是其中蕴含了关于并发、类加载、序列化等⼀系列深层次的知识,如果理解不够深,就有可能在⾼并发时遇到难以预期的异常,或者会造成资源浪费。

所以本⽂会从将⽬前Java领域最常⽤的⼏种单例模式列出来,供⼤家参考。

WHAT维基百科给出了解释、实现的思路以及应该注意的地⽅:单例模式,也叫单⼦模式,是⼀种常⽤的软件设计模式,属于创建型模式的⼀种。

在应⽤这个模式时,单例对象的类必须保证只有⼀个实例存在。

实现单例模式的思路是:⼀个类能返回对象⼀个引⽤(永远是同⼀个)和⼀个获得该实例的⽅法(必须是静态⽅法,通常使⽤getInstance这个名称);当我们调⽤这个⽅法时,如果类持有的引⽤不为空就返回这个引⽤,如果类保持的引⽤为空就创建该类的实例并将实例的引⽤赋予该类保持的引⽤;同时我们还将该类的构造函数定义为私有⽅法,这样其他处的代码就⽆法通过调⽤该类的构造函数来实例化该类的对象,只有通过该类提供的静态⽅法来得到该类的唯⼀实例。

单例模式在多线程的应⽤场合下必须⼩⼼使⽤。

如果当唯⼀实例尚未创建时,有两个线程同时调⽤创建⽅法,那么它们同时没有检测到唯⼀实例的存在,从⽽同时各⾃创建了⼀个实例,这样就有两个实例被构造出来,从⽽违反了单例模式中实例唯⼀的原则。

解决这个问题的办法是为指⽰类是否已经实例化的变量提供⼀个互斥锁(虽然这样会降低效率)。

类图是:WHY正如定义所说,单例模式就是整个内存模型中,只有⼀个实例。

实例少了,内存占⽤就少。

同时,只有⼀个实例,也就只需要构建⼀个对象,计算就少。

深入理解java设计模式之单例模式

深入理解java设计模式之单例模式

深⼊理解java设计模式之单例模式今天看了⼀天的设计模式。

单例模式:常⽤的分为两种懒汉模式和饿汉模式单例模式:1、单例类确保⾃⼰只有⼀个实例。

2、单例类必须⾃⼰创建⾃⼰的实例。

3、单例类必须为其他对象提供唯⼀的实例。

举个例⼦,⽹站的计数器就是单例模式的⼀个体现。

因为总不能打开⼀次⽹址就去new⼀个新的计数器对象。

⽽是⼤家都去⽤⼀个计数器下⾯来点⼲货数据库的连接池⼀般也是使⽤单例模式去实现的。

单例模式常⽤的分为两种懒汉模式://懒汉式单例类.在第⼀次调⽤的时候实例化⾃⼰public class Singleton {private Singleton() {}private static Singleton single=null;//静态⼯⼚⽅法public static Singleton getInstance() {if (single == null) {single = new Singleton();}return single;}}public class Singleton {private static class LazyHolder {private static final Singleton INSTANCE = new Singleton(); //使⽤静态内部类的⽅式实现线程安全,这个没研究。

}private Singleton (){}public static final Singleton getInstance() {return LazyHolder.INSTANCE;}}考虑到线程可能并发的可能,所以懒汉模式是线程不安全的。

然⽽我们可以去使⽤ synchronized 这个⽅法让所有的访问去同步,从⽽实现线程安全但是在⽹上看java有反射机制,通过Java反射机制是能够实例化构造⽅法为private的类的,这⾥姑且先不考虑反射机制。

但是我们的知道!饿汉模式://饿汉式单例类.在类初始化时,已经⾃⾏实例化public class Singleton1 {private Singleton1() {}private static final Singleton1 single = new Singleton1();//静态⼯⼚⽅法public static Singleton1 getInstance() {return single;}}饿汉式在类创建的同时就已经创建好⼀个静态的对象供系统使⽤,以后不再改变,所以天⽣是线程安全的。

java设计模式考试题

java设计模式考试题

java设计模式考试题
设计模式是软件开发中常用的一种思想和方法,它可以帮助我们解决各种常见的软件设计问题。

下面是一些可能出现在Java设计模式考试中的题目:
1. 请列举并简要说明常见的创建型设计模式,并举出在Java 中的实际应用场景。

2. 什么是单例模式?请使用Java代码实现一个线程安全的单例模式。

3. 请解释工厂方法模式和抽象工厂模式的区别,并举出在Java中的实际应用场景。

4. 什么是装饰器模式?请使用Java代码实现一个简单的装饰器模式示例。

5. 解释观察者模式的原理,并使用Java代码演示如何实现观察者模式。

这些题目涉及了设计模式的基本概念、实际应用和代码实现,希望这些问题能够帮助你更好地理解Java设计模式。

如果你有其他问题,欢迎继续提出。

java设计模式之单例模式

java设计模式之单例模式

java设计模式之单例模式详解(设计模式)Design pattern主要经典的设计模式总共有二十三种,现在我们来看看设计模式中第一个经典设计模式单例模式(Singleton)。

单例模式表示一个类只会生成唯一的一个对象。

单例模式有两张实现方式:第一种:publicclass Singleton {publicstaticvoid main(String[] args) {A a1=A.getInstance();A a2=A.getInstance();System.out.println(a1==a2);//判断A类型的引用是否相等,是的话返回true,}}class A{privatestatic A a=new A();//必须用修饰符private,且static修饰,否则无法被静态方法使用private A(){ //构造方法也要设成私有的,这样防止在别的方法里new 一个A。

}publicstatic A getInstance(){ //获得实例,且用static是为了使用方便使用类调用静态方法,因为构造方法已经new,无法生成一个引用啊return a; //将返回A类型的引用 a的地址,即new A();}}第二种:publicclass Singleton {publicstaticvoid main(String[] args) {A a1=A.getInstance();A a2=A.getInstance();System.out.println(a1==a2);//判断A类型的引用是否相等,是的话返回true,}}class A{privatestatic A a;//必须用修饰符private,且static修饰,否则无法被静态方法使用private A(){ //构造方法也要设成私有的,这样在别的方法里就无法new 一个A。

}publicstatic A getInstance(){ //获得实例if(a==null){a=new A();}return a; //将返回A类型的引用 a的地址,即new A();}}总结:单例模式有以下特点:1、单例类只能有一个实例。

Java 设计模式练习题及答案

Java 设计模式练习题及答案

Java 设计模式练习题及答案在学习Java设计模式时,练习题是非常重要的一部分。

通过练习题的实践,可以更好地理解和应用设计模式,提升自己的编程能力。

本文将介绍一些Java设计模式练习题,并提供相应的答案,希望能对读者在设计模式的学习和实践中有所帮助。

一、题目一:单例模式——懒汉式实现问题描述:请编写一个线程安全的懒汉式单例模式。

解答示例:```javapublic class Singleton {private static Singleton instance;private Singleton() {}public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}}```二、题目二:工厂模式——简单工厂实现问题描述:请使用简单工厂模式实现一个计算器,支持加减乘除四种运算。

解答示例:```javapublic class CalculatorFactory {public static Calculator createCalculator(String operator) {Calculator calculator = null;switch (operator) {case "+":calculator = new AddCalculator();break;case "-":calculator = new SubtractCalculator();break;case "*":calculator = new MultiplyCalculator();break;case "/":calculator = new DivideCalculator();break;}return calculator;}}public interface Calculator {double calculate(double num1, double num2);}public class AddCalculator implements Calculator {@Overridepublic double calculate(double num1, double num2) { return num1 + num2;}}public class SubtractCalculator implements Calculator { @Overridepublic double calculate(double num1, double num2) {return num1 - num2;}}// MultiplyCalculator和DivideCalculator类似,省略代码// 使用示例Calculator calculator = CalculatorFactory.createCalculator("+");double result = calculator.calculate(2, 3); // 结果为5```三、题目三:观察者模式问题描述:请设计一个简单的气象站系统,该系统需要实现以下功能:1. 可以添加观察者并实时更新气象数据;2. 当气象数据发生变化时,自动通知所有观察者进行更新。

大数据应用开发(java)1+X模拟习题(含答案)

大数据应用开发(java)1+X模拟习题(含答案)

大数据应用开发(java)1+X模拟习题(含答案)一、单选题(共100题,每题1分,共100分)1、下列赋值操作中,在编译阶段会报错的是?()正确答案:C答案解析:小数的默认类型是 double,不是 float。

此项的正确写法是float num = 10.1f ;或 double num = 10.1 ;2、下列哪项不属于关系型数据库?A、OracleB、SQL ServerC、HBaseD、MySql正确答案:C答案解析:常见关系型数据库有:Oracle、DB2、Microsoft SQL Server、Microsoft Access、MySQLHBase是列式非关系型数据库3、以下哪个函数不能用来处理字符串( )A、length() 函数B、upper() 函数C、concat() 函数D、sqrt() 函数正确答案:D4、在 Java 中,以下代码()正确地创建了一个 InputStreamReader 对象。

正确答案:A答案解析:通通过查阅 API,可知符合 I/O 流语法规范的是 A 选项。

5、下列()异常表示向方法传递了一个不合法或不正确的参数。

A、IllegalAccessExceptionB、IllegalArgumentExceptionC、ClassCastExceptionD、InputMismatchException正确答案:B答案解析:IllegalAccessException 是访问权限不足构成的异常;ClassCastException 是类型转换异常;InputMismatchException 通常是使用 Scanner 输入数据时发生的异常。

6、数据库中删除表MYTABLE的SQL语句是( )。

A、DELETE * FROM MYTABLEB、TRUNCATE TABLE MYTABLEC、DROP TABLE MYTABLED、DELETE FROM MYTABLE正确答案:C答案解析:删除表使用DROP7、以下哪个不是面向对象具有的特性()?A、继承B、封装C、多态D、静态正确答案:D答案解析:继承、封装、多态是面向对象的三大特性。

单例模式的八种写法

单例模式的八种写法

单例模式的八种写法单例模式作为日常开发中最常用的设计模式之一,是最基础的设计模式,也是最需要熟练掌握的设计模式。

单例模式的定义是:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

那么你知道单例模式有多少种实现方式吗?以及每种实现方式的利弊呢?•饿汉模式•懒汉模式(线程不安全)•懒汉模式(线程安全)•双重检查模式(DCL)•静态内部类单例模式•枚举类单例模式•使用容器实现单例模式•CAS实现单例模式
饿汉模式代码如下:public class Singleton { private static Singleton instance = new Singleton(); private Singleton () { } public static Singleton getInstance() { return instance; }}这种方式在类加载时就完成了实例化,会影响类的加载速度,但获取对象的速度快。

这种方式基于类加载机制保证实例仅有一个,避免了多线程的同步问题,是线程安全的。


懒汉模式(线程不安全)绝大多数时候,类加载的时机和对象使用的时机都是分开的,所以没有必要在类加载的时候就去实例化单例对象。

为了消除单例对象实例化对类加载的影响,引入了延迟加载,就有了懒汉模式的实现方式。

代码如下:public class Singleton { private static Singleton instance; pr ivate Singleton () {} public static Singleton getInstance() { if (instance == null) {instance = new Singleton(); } return instance; } }懒汉模式声明了一个静态对象,在用户第一次调用时完成实例化,属于延迟加载方式。

而且这种方式不是线程安全。


懒汉模式(线程安全)针对线程不安全的懒汉模式,对其中的获取单例对象的方法增加同步关键字。

第二章 单例模式练习.

第二章 单例模式练习.

class TestTrafficLight { public static void main(String[] args) { TrafficLight red = TrafficLight.getLight("red"); System.out.println(red); TrafficLight green = TrafficLight.getLight(“green"); System.out.println(green); TrafficLight yellow = TrafficLight.getLight(“yellow"); System.out.println(yellow);
计算机科学与工程学院 No.3/10
public class GenerateID UML与设计模式 第1章 OO方法概述 { private static GenerateID singleton ; private GenerateID(){} public synchronized static GenerateID getInstance(){ if (singleton == null) { singleton = = new GenerateID(); } return singleton; } private long currentID=1000; public long getID(){ return currentID++; } } class TestID { public static void main(String args[]){ GenerateID g1 = GenerateID.getInstance(); GenerateID g2 = GenerateID.getInstance(); System.out.println(g1.getID()); System.out.println(g2.getID()); Singleton System.out.println(g1.getID()); System.out.println(g2.getID()); 代码示例 } }

单例模式详解

单例模式详解

单例模式详解单例模式是一种常用的设计模式,它可以确保一个类只有一个实例,并且提供了全局访问点。

在很多场景下,我们需要确保某个对象只有唯一的实例,比如数据库连接池、线程池等。

1. 什么是单例模式?单例模式是一种创建型设计模式,它能够确保一个类只有一个实例,并且提供了全局访问点。

这意味着无论何时何地都可以通过该类来获取到同一个对象。

2. 单例模式的优缺点优点:(1)节省系统资源:由于单例模式只创建一个对象,在使用过程中不会频繁地创建和销毁对象,从而减少了系统资源的消耗。

(2)方便统一管理:由于所有对该类的访问都通过同一个接口进行调用,因此方便对其进行统一管理和维护。

(3)避免重复操作:由于每次获取到的都是同一个对象,在处理相同业务逻辑时不会出现重复操作导致数据错误或者异常情况发生。

缺点:(1)可能造成性能问题:如果某个应用程序中存在大量使用单例模式的代码,则可能会影响整体性能表现。

因为在并发环境下需要加锁来控制多线程同时访问共享资源所带来额外开销。

(2)难以扩展功能:如果要扩展某个已经实现为单例形态的类,则必须修改原代码,在没有完善测试工具支持下可能引入新问题甚至破坏原有功能结构等风险。

3. 单利模式应用场景当以下条件满足之后考虑采用单利设计:(1)需要频繁创建和销毁某些资源;(2)需要全局共享访问权限;4. 实现方式饿汉方式:public class Singleton {private static final Singleton instance = new Singleton();private Singleton() {}public static Singleton getInstance() {return instance;}}懒汉方式:public class Singleton {private static volatile Singleton instance = null;private Singleton() {}public static synchronized Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}}5. 总结总之,单利设计就像其他任何技术选择那样也具备自身特定优劣势及适合范围限制。

Java中的单例模式

Java中的单例模式

Java中的单例模式在软件⼯程中,单例模式是⼀种软件设计模式,它将类的实例化限制为⼀个“单个”实例。

当恰好需要⼀个对象来协调整个系统中的动作时,这很有⽤。

通常,这是通过以下⽅式完成的: 声明该类的所有构造函数为私有 和提供⼀个静态⽅法,该⽅法返回对该实例的引⽤饿汉式:该实例通常存储为私有静态变量。

在初始化变量时,即在⾸次调⽤静态⽅法之前的某个时刻,创建了实例。

以下是⽤Java编写的⽰例实现。

public final class Singleton {private static final Singleton INSTANCE = new Singleton();private Singleton() {}public static Singleton getInstance() {return INSTANCE;}}懒汉式:单例实现可以使⽤延迟初始化,在⾸次调⽤静态⽅法时创建实例。

如果可能同时从多个线程调⽤静态⽅法,则可能需要采取措施来防⽌可能导致创建该类的多个实例的竞争条件。

以下是使⽤Java编写的使⽤带双重检查锁定的延迟初始化的线程安全⽰例实现。

public final class Singleton {private static volatile Singleton instance = null;private Singleton() {}public static Singleton getInstance() {if (instance == null) {synchronized(Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}}总结: 单例模式通过私有构造函数并提供⼀个静态⽅法返回该实例 单例模式分为懒汉式和饿汉式 饿汉式在Class加载的时候就创建了该实例,不会出现线程安全的问题 懒汉式是在程序调⽤的时候创建实例,会出现线程安全的问题。

JAVA设计模式之单例模式(网上搜集整理版)

JAVA设计模式之单例模式(网上搜集整理版)

JAVA设计模式之单例模式一、单例模式的介绍Singleton是一种创建型模式,指某个类采用Singleton模式,则在这个类被创建后,只可能产生一个实例供外部访问,并且提供一个全局的访问点。

全局对象和Singleton模式有本质的区别,因为大量使用全局对象会使得程序质量降低,而且有些编程语言根本不支持全局变量。

最重要的是传统的全局对象并不能阻止一个类被实例化多次。

Effecttive Java第二版中最新单例模式从Java 1.5发行版本起,实现Singleton的方法只需编写一个包含单个元素的枚举类型:// Enum singleton - the preferred approach - page 18public enum Elvis {INSTANCE;public void leaveTheBuilding() {System.out.println("Whoa baby, I'm outta here!");}// This code would normally appear outside the class!public static void main(String[] args) {Elvis elvis = Elvis.INSTANCE;elvis.leaveTheBuilding();}}这种方法在功能上与公有域方法相近,但是它更加简洁,无偿地提供了序列化机制,绝对防止多次实例化,即使是在面对复杂的序列化或者反射攻击的时候。

虽然这种方法还没有广泛采用,但是单元素的枚举类型已经成为实现Singleton的最佳方法单例类只能有一个实例单例类必须自己创建自己的唯一实例。

单例类必须给所有其他对象提供这一实例。

三、单例模式的应用每台计算机可以由若干个打印机,但只能有一个Printer Spooler,避免有两个作业同时输出到打印机。

一个具有自动编号主键的表可以有多个用户同时使用,但数据库中只能有一个地方分配下一个主键。

javascript单例模式详解及简单实例

javascript单例模式详解及简单实例

javascript单例模式详解及简单实例javascript 单例模式详解及简单实例在Javascript中,单例模式是一种最基本又经常用到的设计模式,可能在不经意间就用到了单例模式。

本文将从最基础的理论开始,讲述单例模式的基本概念和实现,最后用一个例子来讲述单例模式的应用。

理论基础概念单例模式,顾名思义就是只有一个实例存在。

通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。

如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。

基本结构最简单的单例模式起始就是一个对象字面量,它将有关联的属性和方法组织到一起。

var singleton = { prop:"value", method:function(){ }}这种形式的单例模式,所有成员都是公开的,都可以通过singleton来访问。

这样的缺点是单例中有一些辅助的方法并不希望暴露给使用者,如果使用者用了这些方法,然后在后面维护的时候,一些辅助方法被删除,这样会造成程序错误。

如何避免这样从的错误呢?包含私有成员的单例模式要怎么在类中创建私有成员呢,这通过需要闭包来进行实现,关于闭包的知识,本文不再赘述,大家可以自行Google。

基本形式如下:var singleton = (function () { var privateVar = "private"; return { prop: "value", method: function () { console.log(privateVar); } } })();首先是一个自执行的匿名函数,在匿名函数中,声明了一个变量privateVar,返回一个对象赋值给单例对象singleton。

在匿名函数外部无法访问到privateVar变量,它就是单例对象的私有变量,只能在函数内部或通过暴露出来的'方法去访问这个私有变量。

设计模式习题

设计模式习题

1、设计模式一般用来解决什么样的问题()A.同一问题的不同表相 B不同问题的同一表相C.不同问题的不同表相D.以上都不是2、下列属于面向对象基本原则的是( )A.继承B.封装C.里氏代换D都不是3、Open-Close原则的含义是一个软件实体( )A.应当对扩展开放,对修改关闭.B.应当对修改开放,对扩展关闭C.应当对继承开放,对修改关闭D.以上都不对4、要依赖于抽象,不要依赖于具体。

即针对接口编程,不要针对实现编程,是( )的表述A.开-闭原则B.接口隔离原则C.里氏代换原则D.依赖倒转原则5、单例模式中,两个基本要点( )和单例类自己提供单例A.构造函数私有B.唯一实例C.静态工厂方法D.以上都不对6、“不要和陌生人说话” 是( )原则的通俗表述A.接口隔离B.里氏代换C.依赖倒转D.迪米特:一个对象应对其他对象尽可能少的了解7、单子(单例,单态)模式表述的不正确的是( )A.一个单例类中,最多可以有一个实例.B.表示单例类中有不多于一个的实例C.单例类中可以没有任何实例D.单例类可以提供其他非自身的实例8、在观察者模式中,表述错误的是()A.观察者角色的更新是被动的。

B.被观察者可以通知观察者进行更新C.观察者可以改变被观察者的状态,再由被观察者通知所有观察者依据被观察者的状态进行。

D.以上表述全部错误。

9.对于违反里式代换原则的两个类,可以采用的候选解决方案错误的是:()A.创建一个新的抽象类C,作为两个具体类的超类,将A 和B 共同的行为移动到C 中,从而解决A和B 行为不完全一致的问题。

B.将B到A的继承关系改组成委派关系。

C.区分是“IS-a”还是”Has-a”。

如果是“Is-a”,可以使用继承关系,如果是”Has -a”应该改成委派关系D.以上方案皆错误10.关于继承表述错误的是:()A.继承是一种通过扩展一个已有对象的实现,从而获得新功能的复用方法。

B.泛化类(超类)可以显式地捕获那些公共的属性和方法。

设计模式之单例模式

设计模式之单例模式

单例模式:概念: 单例模式,顾名思义就是一个类只有一个实例,并且类负责创建自己的对象,其构造方法被隐藏,提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

实例:一个班级只能有一个班主任;一个国家只能有一个国家主席.单例模式共分为两大类:•饿汉式:实例在类装载时创建•懒汉式:实例在第一次使用时创建饿汉式按照定义我们可以写出一个基本代码:public class Singleton {// 创建一个Singleton的对象private static Singleton instance = new Singleton();// 使用private将构造方法私有化,防止外界通过该构造方法创建多个实例private Singleton (){}// 提供唯一获取实例的方法,添加static,将该方法变成类所有,通过类名访问public static Singleton getInstance() {return instance;} }优点:线程安全,方便缺点: 类加载时就初始化(我先把对象(面包)创建好,等我要用(吃)的时候直接来拿就行了),浪费资源(这是相对的:我事先就做好了很多面包,但是并不一定吃,这样容易造成资源的浪费;我就做几个面包,虽然并不一定吃,但也不至于造成资源上的浪费)懒汉式1.简单懒汉式:public class Singleton {//创建一个对象实例private static Singleton instance;//定义一个私有的构造方法private Singleton (){}//提供唯一获取实例的方法public static Singleton getInstance() {//每次调用getInstance()方法,获取instance之前先进行判断,如果instance为空就new一个对象出来,否则就直接返回已存在的对象.if (instance == null) {instance = new Singleton();}return instance;} }优点:节省资源缺点:线程不安全(比如这两个线程都调用getInstance(),同时进入到if (instance == null),都判断为null[第一个线程判断为空之后,并没有继续向下执行,当第二个线程判断的时候instance依然为空],最终两个线程就各自会创建一个实例出来)2.简单懒汉式扩展版:public class Singleton {private static Singleton instance;private Singleton (){}//使用synchronized,给getInstance()方法加上一个同步锁,保证实例的唯一性public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;}}原理:如果有两个线程(Thread1、Thread2)同时执行到这个方法时,其中一个线程Thread1获得同步锁,得以继续执行,而另一个线程Thread2则需要等待,当第Thread1执行完毕getInstance()方法之后(完成了null判断、对象创建、获得返回值之后),Thread2线程才会执行,这时因为对象已经存在,就不会进入到if里面,而是直接返回这个已存在的对象,从而保证了实例的唯一性.优点:线程安全,节省资源缺点:会强制除Thread1之外的所有线程等待,对程序的执行效率造成负面影响3.双检锁/双重校验锁(DCL,即double-checked locking)public class Singleton {//volatile关键字解决指令重排的问题private volatile static Singleton singleton;private Singleton (){}public static Singleton getSingleton() {//第一个if(singleton ==null),其实是为了解决代码二中的效率问题,只有singleton 为null的时候,才进入synchronized的代码段,大大减少了几率if (singleton == null) {//加一个同步块,由于锁机制的互斥性:即在同一时间只允许一个线程持有某个对象锁,类对象是唯一的,实现同步运行.synchronized (Singleton.class) {//第二个if(singleton==null),则是跟代码二一样,是为了防止可能出现多个实例的情况.if (singleton == null) {singleton = new Singleton(); }}}return singleton;} }优点: 线程安全,节省资源缺点:不太美观.4. 登记式/静态内部类public class Singleton {//被static修饰的内部类可以直接作为一个普通类来使用,而不需实例一个外部类private static class SingletonHolder {//定义一个常量INSTANCE, 一旦给值,就不可修改,并且可以通过类名访问, 确保了实例的唯一性.private static final Singleton INSTANCE = new Singleton();}private Singleton (){//if(SingletonHolder.INSTANCE!=null){//throw new RuntimeException(“不能非法创建对象”);//}}public static final Singleton getInstance() {//内部类在使用的时候才会被加载return SingletonHolder.INSTANCE;}}优点:线程安全,节约资源缺点:通过反射创建对象就不是单例public class BreakSingleton{public static void main(String[] args) throw Exception{//获取类对象Class clazz = Class.forName("Singleton");//通过类对象的getDeclaredConstructor()方法获得构造器(Constructor)对象并调用其newInstance()方法创建对象Constructor c = clazz.getDeclaredConstructor(null);//强制访问private定义的构造方法c.setAccessible(true);Singleton s1 = c.newInstance();Singleton s2 = c.newInstance();//通过反射,得到的两个不同对象System.out.println(s1);System.out.println(s2);}}6. 枚举public enum Singleton {//列出一个枚举实例INSTANCE;//获取INSTANCE指向的实例对象public static Singleton getInstance() {return INSTANCE;}}保证实例唯一:从枚举的常量字典中获取一个枚举类型的对象, 枚举的常量字典相当于是一个map,当这个枚举类创建好了以后,这个对象就会被存在常量字典中,通过key(INSTANCE)去获取这个实例对象.防反射机制破解单例模式:在其构造方法中加一个判断,来防止通过反射创建实例对象.。

(转)单例模式超全整理(面试中常见的题目)

(转)单例模式超全整理(面试中常见的题目)

(转)单例模式超全整理(⾯试中常见的题⽬)单例模式虽然简单,却是⾯试中经常出现的⼀类问题。

1 单例模式单例模式的特点:⼀是某个类只能有⼀个实例⼆是它必须⾃⾏创建这个实例三是它必须⾃⾏向整个系统提供这个实例应⽤情况:对于多个对象使⽤同⼀个配置信息时,就需要保证该对象的唯⼀性。

如何保证对象的唯⼀性?⼀不允许其他程序⽤new创建该类对象。

⼆在该类创建⼀个本类实例三对外提供⼀个⽅法让其他程序可以获取该对象实现的⽅法:⼀是构造函数私有化⼆是类定义中含有⼀个该类的静态私有对象三是该类提供了⼀个静态的公共的函数⽤于创建或获取它本⾝的静态私有对象⽅法⼀饿汉式public class Person1 {//定义该类的静态私有对象private static final Person1 person1 =new Person1();//构造函数私有化private Person1(){};//⼀个静态的公共的函数⽤于创建或获取它本⾝的静态私有对象public static Person1 getPerson1() {return person1;}}该⽅法虽然在多线程下也能正确运⾏但是不能实现延迟加载()资源效率不⾼,可能getPerson1()永远不会执⾏到,但执⾏该类的其他静态⽅法或者加载了该类(class.forName),那么这个实例仍然初始化⽅法⼆懒汉式public class Person1 {private static Person1 person1 =null;private Person1(){}public static Person1 getPerson1() {if(person1==null){person1=new Person1();}return person1;}}该⽅法只能在单线程下运⾏,当在多线程下运⾏时可能会出现创建多个实例的情况。

对该⽅法可以进⾏优化懒汉式(优化⼀)public class Person1 {private static Person1 person1 =null;private Person1(){}public static synchronized Person1 getPerson1() {if(person1==null){person1=new Person1();}return person1;}}该⽅法虽然能保证多线程下正常运⾏,但是效率很低,因为 person1=new Person1(); 这句话在整个程序运⾏中只执⾏⼀次,但是所有调⽤getPerson1的线程都要进⾏同步,这样会⼤⼤减慢程序的运⾏效率。

软件设计——单例模式之学生唯一学号C++

软件设计——单例模式之学生唯一学号C++

软件设计——单例模式之学⽣唯⼀学号C++ 1、类图2、代码#include<iostream>#include<string>using namespace std;class StudentNo{private:static StudentNo *student;string no;StudentNo() {};void setStudentNo(string no1){no = no1;}public:static StudentNo * getStudent() {if (student == NULL) {cout << "第⼀次分配学号,分配新学号!" << endl;student = new StudentNo();student->setStudentNo("20194023");}else {cout << "学号已存在,获取旧学号!" << endl;}return student;}string getStudentNo() {return no;}};StudentNo * StudentNo::student = NULL; //初始化 studentint main() {StudentNo * no1, *no2;no1 = StudentNo::getStudent();no2 = StudentNo::getStudent();cout << "学号是否⼀致:" << (no1 == no2) << endl;string str1, str2;str1 = no1->getStudentNo();str2 = no2->getStudentNo();cout << "第⼀次学号" << str1 << endl;cout << "第⼆次学号" << str2 << endl;cout << "内容是否相等" << (!pare(str2)) << endl; //str1 == str2 时值为0cout << "是否相同对象" << (str1 == str2) << endl;}3、运⾏截图。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
计算机科学与工程学院 No.3/10
public class GenerateID UML与设计模式 第1章 OO方法概述 { private static GenerateID singleton ; private GenerateID(){} public synchronized static GenerateID getInstance(){ if (singleton == null) { singleton = = new GenerateID(); } return singleton; } private long currentID=1000; public long getID(){ return currentID++; } } class TestID { public static void main(String args[]){ GenerateID g1 = GenerateID.getInstance(); GenerateID g2 = GenerateID.getInstance(); System.out.println(g1.getID()); System.out.println(g2.getID()); Singleton System.out.println(g1.getID()); System.out.println(g2.getID()); 代码示例 } }
}
}
课堂练习
下面的TicketMaker类每次调用 getNextTicketNumber方法时,就会依次返 回1000,1001,1002,...。如果按照现在的方 式,TicketMaker类可以产生无限个对象实 例。请把Singleton模式应用到此类,让它只会 产生一个对象实例。 成为Singleton模式之前的TicketMaker类: public class TicketMaker{ private int ticket=1000; public int getNextTicketNumber(){ return ticket++; } }
计算机科学与工程学院
No.2/10
public class GenerateID UML与设计模式 第1章 OO方法概述 { private static GenerateID singleton = new GenerateID(); private GenerateID(){} public static GenerateID getInstance(){ return singleton; } private long currentID=1000; public long getID(){ return currentID++; } } class TestID { public static void main(String args[]){ GenerateID g1=GenerateID.getInstance(); GenerateID g2=GenerateID.getInstance(); System.out.println(g1.getID()); System.out.println(g2.getID()); Singleton System.out.println(g1.getID()); System.out.println(g2.getID()); 代码示例 } }
public class TicketMaker { private int ticket = 1000; private static TicketMaker singleton = new TicketMaker(); private TicketMaker() { } public static TicketMaker getInstance() { return singleton; } public synchronized int getNextTicketNumber() { return ticket++; } }
class TestTrafficLight { public static void main(String[] args) { TrafficLight red = TrafficLight.getLight("red"); System.out.println(red); TrafficLight green = TrafficLight.getLight(“green"); System.out.println(green); TrafficLight yellow = TrafficLight.getLight(“yellow"); System.out.println(yellow);
UML与设计模式
第 1章
OO方法概述
Hale Waihona Puke 第二章 单例模式练习2014年3月
计算机科学与工程学院
No.1/10
UML与设计模式
第 1章
OO方法概述
Singleton设计模式
练习:使用Singleton模式,编写并 测试GenerateID类,生成唯一ID 值 private long currentID=1000; public long getID()
计算机科学与工程学院 No.4/10
UML与设计模式
第 1章
OO方法概述
Singleton设计模式
作业:编写TrafficLight类,使其只有 红,黄,绿三个实例(使用HashMap)
HashMap键值对应(key,value),一个key对应 一个值。知道key就可以取到对应的值。 Map map = new HashMap(); map.put("xxx",new TrafficLight("xxx")); map.put("yyy",new TrafficLight("yyy")); Object o=map.get("xxx"); TrafficLight t=(TrafficLight).get("xxx");
计算机科学与工程学院 No.5/10
import java.util.*; public class TrafficLight { private String color ; private static Map map = new HashMap(); private TrafficLight(String color){ this.color = color; } public synchronized static TrafficLight getLight(String color){ if (map.size()==0) { map.put("red", new TrafficLight("red")); map.put("yellow", new TrafficLight("yellow")); map.put("green", new TrafficLight("green")); } return (TrafficLight)map.get(color); } public String toString(){ return "Current color : " +color; } }
public class Main { public static void main(String[] args) { System.out.println("Start."); for (int i = 0; i < 10; i++) { System.out.println(i + ":" + TicketMaker.getInstance(). getNextTicketNumber()); } System.out.println("End."); } }
相关文档
最新文档