设计模式(一)—单例模式

最后更新于:2022-04-01 16:25:53

## 单例模式 英文名称:(Singleton Pattern) **定义**:确保某一个类只用一个实例,而且自行实例化并向整个系统提供这个实例 UML图: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-06-06_57553407ce5ab.jpg) ~~~ public class SingletonTest { public static void main(String[] args) { //通过Singleton对外暴漏的方法,进行实例化。并保证只有一个实例 Singleton single = Singleton.getInstance(); System.out.println(single.toString()); } } //又称饿汉式单例模式 class Singleton{ private static final Singleton single = new Singleton(); private Singleton(){ } public static Singleton getInstance(){ return single; } } //又称懒汉式单例模式 //<span style="font-size:18px;">懒汉式单例模式在遇到高并发情况,系统有压力增大,可能会出现多个实例的对象。</span> class Singleton1{ private static Singleton1 single = null; private Singleton1(){ } public static Singleton1 getInstance(){ if(single==null){ synchronized (Singleton1.class) { // if(single==null){ single = new Singleton1(); } } } return single; } } ~~~ **(按照书本上的总结,自己理解并不太深刻。。)** **单例模式的优点:** 1、单例模式内存中只有一个实例,减少内存开支,一个对象需要频繁的创建和销毁。使用单例模式具有很大的优势。 2、单例只生成一个实例,减少系统的性能开销。 3、单例模式可以在避免对资源的多重占用。 4、单例模式可以在系统设置全局的访问点,优化和共享资源访问。 **单例模式的缺点:** 1、单例模式一般没有接口,扩展很困难。 2、单例对测试不利 3、单例与单一职责原则有冲突。 **单例的使用场景:** 1、要求生成唯一序列号的环境 2、在整个项目中需要一个共享访问点或访问数据 3、创建一个对象需要消耗的资源过多 4、需要定义大量的静态常量和静态方法。 **单例的拓展** 通过单例的拓展,让类只产生两个或者多个实例对象。 UML图 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-06-06_57553407e4478.jpg) ~~~ public class EmperorTest { public static void main(String[] args) { for(int i=0;i<5;i++){ //获取Emperor对象的实例 Emperor e = Emperor.getEmperor(); e.say(); } } } class Emperor{ //定义一个list集合,用来存放对象的实例 private static List<Emperor> listEmperor = new ArrayList<Emperor>(); private static int maxNum = 2; //定义一个list集合,为创建的对象设置编号。 private static List<String> listNumofEmperor = new ArrayList<String>(); //表示当前编号 private static int currentNum = 0; //创建出所有的对象 static{ for(int i=0;i<maxNum;i++) listEmperor.add(new Emperor("实例化.."+(i+1)+"..对象")); } private Emperor(String name){ listNumofEmperor.add(name); } public static Emperor getEmperor(){ Random random = new Random(); currentNum = random.nextInt(maxNum); return listEmperor.get(currentNum); } public void say(){ System.out.println(listNumofEmperor.get(currentNum)); } } ~~~
';