Java设计模式——单例模式

    设计模式是一种前人通过实际的开发经验,总结出来的一种设计思想。为了代码的可重用性、可靠性、简洁性的优点。设计模式和具体的编程语言无关,学习设计模式就是要建立面向对象的思想,尽可能的使用面向接口的编程。是代码之间低耦合、高内聚。

1. 设计模式概述

1.1 常见设计模式

    根据我目前的学习范围,在某些知识点所涉及到的设计模式如下:

  • 模版方法模式(抽象类)
  • 简单工厂模式、工厂方法模式(接口)
  • 单例设计模式
  • 装饰者设计模式
  • 适配器模式

1.2 设计模式的设计原则

  • 单一职责原则---高内聚、低耦合
  • 开闭原则      ---一个对象对扩展开放,对修改关闭
  • 里氏替换原则---在任何父类出现的地方都可以用它的子类来替代
  • 依赖注入原则---要依赖于抽象,不要依赖于具体实现。如前段时间学习的spring
  • 接口分离原则---不应该强迫程序依赖他们不需要使用的方法
  • 迪米特原则   ---一个对象应当对其他对象尽可能少的了解

1.3 设计模式的分类

  • 创建型模式---对象的创建

        简单工厂模式、工厂方法模式、单例模式、抽象工厂模式、建造者模式、原型模式。(6个)

  • 结构性模式---对象的组成,也就是对象的结构

        适配器模式、代理模式、装饰模式、外观模式、桥接模式、组合模式、享元模式。(7个)

  • 行为型模式---对象的行为

        模版方法模式、观察者模式、状态模式、职责链模式、命令模式、访问者模式、策略模式、

        备忘录模式、迭代器模式、解释器模式。(10个)


2. 单例设计模式

2.1  饿汉式

    类刚一加载就创建单实例化对象。

Person.java

package com.ilaoda.day01;

/**
 * 单例设计模式
 * 	饿汉式---Person类刚一加载就创建对象
 * 
 * 怎样才能保证单例模式呢?我们从创建对象的条件入手:
 * 	1. 让构造方法私有化,这样外界不能调用构造方法创建对象
 * 	2. 在该类的成员位置自己创建实例化对象(只有这么一个)
 * 	3. 提供一个公共的方法,可以在外界获取这个唯一的实例化对象
 * @author iLaoda
 *
 */
public class Person {
	
	/*
	 * 构造方法私有化
	 * 	private---不让外界调用构造方法
	 */
	private Person() {
		
	}
	
	/*
	 * 自己创建一个对象
	 * 	private---不让外界随意修改person引用的值,要不不能体现单例
	 * 	static ---下面公共的方法是static静态的,只能访问静态成员
	 */
	
	private static Person person = new Person();
	
	/*
	 * 对外提供公共的获取对象
	 * 	static---因为外界不能创建该类对象,只能自己给外界提供。
	 * 		 而且要让外界获得,在外只能类名.静态方法调用
	 */
	public static Person getPerson() {
		return person;
	}
}

TestPerson.java

package com.ilaoda.day01;

/**
 * 单例模式测试类
 * 	饿汉式---Person类刚一加载就创建对象
 * @author iLaoda
 *
 */
public class TestPerson {
	public static void main(String[] args) {
		
		Person p1 = Person.getPerson();
		Person p2 = Person.getPerson();
		
		System.out.println(p1 == p2);  // true,证明是单例
		
		//Person.s = null;  如果Person类中,创建对象语句不private,就可以被外界修改,不能体现单例
	}
}
打印结果:true


2.2 懒汉式

Student.java

package com.ilaoda.day01;

/**
 * 单例设计模式
 * 	懒汉式---用的时候才创建对象
 * @author Administrator
 *
 */
public class Student {
	
	/*
	 * 构造方法私有化
	 * 	private---不让外界调用构造方法
	 */
	private Student() {
		
	}
	
	/*
	 * 自己创建一个对象
	 * 	null ---表明此刻没有创建对象,到用的时候再创建(体现懒汉式)
	 * 	private---不让外界随意修改person引用的值,要不不能体现单例
	 * 	static ---下面公共的方法是static静态的,只能访问静态成员
	 */
	private static Student t = null;
	
	/*
	 * 对外提供公共的获取对象
	 * 	static---因为外界不能创建该类对象,只能自己给外界提供。
	 * 			  而且要让外界获得,在外只能类名.静态方法调用
	 * 	synchronized---线程同步,使创建对象时安全,只能创建这一个对象
	 */
	public synchronized static Student getStudent() {
		// 判断student为空,才创建对象
		// 假设t1已经进入判断体中,还每没创建对象时,这时,t2、t3线程也进入了判断体中
		// 当一次创建对象完毕之后,外部想再次得到对象,此时对象已经不是null,直接return t;
		if (t == null) {
			// 如果t1 t2 t3三个线程都进来,势必产生了三个对象,所以不符合单例的要求
			// 因此,声明该方法为同步的,这样保证每次只有一个线程进来
			t =  new Student();
		}
		return t;	
	}
}

TestStudent.java


package com.ilaoda.day01;

/**
 * 
 * 单例设计模式--测试类
 * 	懒汉式---用的时候才创建对象
 * @author iLoada
 *
 */
public class TestStudent {
	public static void main(String[] args) {
		
		Student t1 = Student.getStudent();
		Student t2 = Student.getStudent();
		
		System.out.println(t1 == t2);  // true
	}
}



3. 两种单例模式的分析

    针对饿汉式和懒汉式,有不同的侧重点。

  • 饿汉式

        (1) 开发时候用

        (2) 不会出现线程不安全的问题

  • 懒汉式

        (1) 找工作时候写这种

        (2) 会出现懒加载问题,也就是延迟加载

        (3) 会出现线程安全问题

            * 多线程环境(如果有这种情况)

            * 有共享数据(t对象共享)

            * 有多条语句操作共享数据(t == null,  t = new Student;  而在饿汉式中没有)


4. 另外

    如果本文若存在错误,欢迎批评指正,一起学习交流。

        


        


你可能感兴趣的:(懒汉式,单例设计模式,饿汉式)