一:设计模式的分类:
设计模式分为3种类型,共23种;
1:创建型模式:单例模式;抽象工厂模式;原型模式;建造者模式;工厂模式.
2:结构型模式:适配器模式;桥接模式;装饰模式;组合模式;外观模式;享元模式;代理模式.
3:行为型模式:模板方法模式;命令模式;访问者模式;迭代器模式;观察者模式;中介者模式;备忘录模式;解释器模式;状态模式;策略模式;职责链模式(责任链模式)
二:创建型模式:
1:单例模式:
说明:单例模式就是保证某一个类在整个系统中只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法;
2:单例模式一共有8种写法:
2.1:饿汉式(静态常量);
2.2:饿汉式(静态代码块);
2.3:懒汉式(线程不安全);
2.4:懒汉式(线程安全;同步方法);
2.5:懒汉式(线程安全;同步代码块);
2.6:双重检查;
2.7:静态内部类;
2.8:枚举;
3:应用实例:
3.1:饿汉式(静态常量)
步骤:
1:构造器私有化;(目的是为了防止new创建对象实例)
2:在类的内部创建对象实例
3:向外暴露一个静态的公共方法 getInstance
4:代码实现
**
* 饿汉式 (静态变量)
*/
public class SingleType01 {
public static void main(String[] args) {
//测试 获取两次实例 看是否相同
Single instance = Single.getInstance();
Single instance1 = Single.getInstance();
if (instance == instance1){
System.out.println("你们是相同的;不用担心 ;一切OK");
}
}
static class Single {
//第一步 先将构造器私有化;私有化后,外部将不能通过new 的方式来创建示例对象
private Single() {
}
//第二步 奔雷内部创建对象实例
private final static Single instance = new Single();
//创建一个共有静态方法,返回实例对象
public static Single getInstance() {
return instance;
}
}
}
5:模式分析:
优缺点说明:
3.2:饿汉式(静态代码块)
/**
* 饿汉式 (静态代码块)
*/
public class SingleType02 {
public static void main(String[] args) {
//测试 获取两次实例 看是否相同
Single instance = Single.getInstance();
Single instance1 = Single.getInstance();
if (instance == instance1) {
System.out.println("你们是相同的;不用担心 ;一切OK");
}
}
static class Single {
//第一步 先将构造器私有化;私有化后,外部将不能通过new 的方式来创建示例对象
private Single() {
}
//第二步 奔雷内部创建对象实例
private final static Single instance;
//静态代码块
static {
instance = new Single();
}
//创建一个共有静态方法,返回实例对象
public static Single getInstance() {
return instance;
}
}
}
//代码分析:在类加载的时候就进行初始化 ;可能造成内存浪费
3.3 懒汉式(线程不安全)
/**
* 懒汉式 (线程不安全的) 只有调用getInstance 方法时才会创建对象
*/
public class SingleType03 {
public static void main(String[] args) {
//测试 获取两次实例 看是否相同
Single instance = Single.getInstance();
Single instance1 = Single.getInstance();
if (instance == instance1) {
System.out.println("你们是相同的;不用担心 ;一切OK");
System.out.println("instance+hashcode ==="+ instance.hashCode());
System.out.println("instance1+hashcode === "+ instance1.hashCode());
}
}
static class Single {
//第一步 先将构造器私有化;私有化后,外部将不能通过new 的方式来创建示例对象
private Single() {
}
//第二步 内部创建对象实例
private static Single instance;
//创建一个共有静态方法,返回实例对象 ;只有调用改方法的时候才会创建对象,否则不会创建
public static Single getInstance() {
if (instance==null){
return instance = new Single();
}
return instance;
}
}
}
模式分析:
优缺点说明:
3.4 懒汉式(线程安全,同步方法 synchronized )
/**
* 懒汉式 (线程安全;同步方法) 只有调用getInstance 方法时才会创建对象
*/
public class SingleType04 {
public static void main(String[] args) {
//测试 获取两次实例 看是否相同
Single instance = Single.getInstance();
Single instance1 = Single.getInstance();
if (instance == instance1) {
System.out.println("你们是相同的;不用担心 ;一切OK");
System.out.println("instance+hashcode ==="+ instance.hashCode());
System.out.println("instance1+hashcode === "+ instance1.hashCode());
}
}
static class Single {
//第一步 先将构造器私有化;私有化后,外部将不能通过new 的方式来创建示例对象
private Single() {
}
//第二步 内部创建对象实例
private static Single instance;
//创建一个共有静态方法,返回实例对象 ;只有调用改方法的时候才会创建对象,否则不会创建
public static synchronized Single getInstance() {
if (instance==null){
return instance = new Single();
}
return instance;
}
}
}
//代码分析 虽然解决了线程不安全的问题 但是效率太低了 在项目中不推荐使用
3.5 懒汉式(线程安全,同步代码块 synchronized(){} )
/**
* 懒汉式 (线程安全;同步代码块) 只有调用getInstance 方法时才会创建对象
*/
public class SingleType05 {
public static void main(String[] args) {
//测试 获取两次实例 看是否相同
Single instance = Single.getInstance();
Single instance1 = Single.getInstance();
if (instance == instance1) {
System.out.println("你们是相同的;不用担心 ;一切OK");
System.out.println("instance+hashcode ==="+ instance.hashCode());
System.out.println("instance1+hashcode === "+ instance1.hashCode());
}
}
static class Single {
//第一步 先将构造器私有化;私有化后,外部将不能通过new 的方式来创建示例对象
private Single() {
}
//第二步 内部创建对象实例
private static Single instance;
//创建一个共有静态方法,返回实例对象 ;只有调用改方法的时候才会创建对象,否则不会创建
public static synchronized Single getInstance() {
if (instance==null){
synchronized (Single.class){
instance = new Single();
}
}
return instance;
}
}
}
3.5 双重检查;
可以将 线程安全 与效率的问题都 得到解决 并且可以实现懒加载 ;使用关键字 Volatile
/**
*双重检查 只有调用getInstance 方法时才会创建对象
*/
public class SingleType06 {
public static void main(String[] args) {
//测试 获取两次实例 看是否相同
Single instance = Single.getInstance();
Single instance1 = Single.getInstance();
if (instance == instance1) {
System.out.println("你们是相同的;不用担心 ;一切OK");
System.out.println("instance+hashcode ==="+ instance.hashCode());
System.out.println("instance1+hashcode === "+ instance1.hashCode());
}
}
static class Single {
//第一步 先将构造器私有化;私有化后,外部将不能通过new 的方式来创建示例对象
private Single() {
}
//第二步 内部创建对象实例 volatile 关键字的作用 可以保证工作内存中的值 立即更新到主内存 可以理解为轻量级的synchronized
private static volatile Single instance;
//创建一个共有静态方法,返回实例对象 ;只有调用改方法的时候才会创建对象,否则不会创建
public static Single getInstance() {
//只能有一个线程进去每次
//第一次检查
if (instance == null) {
synchronized (Single.class) {
//第二次检查
if (instance == null) {
instance = new Single();
}
}
}
return instance;
}
}
}
3.7:静态内部类;
静态内部类的特点:
1:当外部的类被装载的时候,静态内部类并不会被立即被加载
2:静态都是用来修饰类的内部成员的。比如静态方法,静态成员变量,静态常量。它唯一的作用就是随着类的加载(而不是随着对象的产生)而产生,以致可以用类名+静态成员名直接获得。
3:静态内部类只会加载一次,并且加载过程中 ,是线程安全的;
/**
* 静态内部类 只有调用getInstance 方法时才会创建对象
*/
public class SingleType07 {
public static void main(String[] args) {
//测试 获取两次实例 看是否相同
Single instance = Single.getInstance();
Single instance1 = Single.getInstance();
if (instance == instance1) {
System.out.println("你们是相同的;不用担心 ;一切OK");
System.out.println("instance+hashcode ==="+ instance.hashCode());
System.out.println("instance1+hashcode === "+ instance1.hashCode());
}
}
//在Single 类装载的时候,并不会导致 静态内部类 SingleInstance 的装载 从而保证懒加载的实现
static class Single {
//第一步 先将构造器私有化;私有化后,外部将不能通过new 的方式来创建示例对象
private Single() {
}
//第二步 静态内部类创建对象实例
private static class SingleInstance{
private static final Single INSTANCE =new Single();
}
//创建一个共有静态方法,返回实例对象 ;只有调用改方法的时候才会创建对象,否则不会创建
public static Single getInstance() {
//调用静态内部类的静态属性INSTANCE 导致静态内部类装载 JVM在装载类的时候是线程安全的
return SingleInstance.INSTANCE;
}
}
}
3.8:枚举;
/**
* 枚举;
*/
public class SingleType08 {
public static void main(String[] args) {
//测试 获取两次实例 看是否相同
Single instance = Single.INSTANCE ;
Single instance1 = Single.INSTANCE;
if (instance == instance1) {
System.out.println("你们是相同的;不用担心 ;一切OK");
System.out.println("instance+hashcode ==="+ instance.hashCode());
System.out.println("instance1+hashcode === "+ instance1.hashCode());
}
}
//使用枚举 可以实现单例 并且实现 懒加载 保证线程安全
enum Single{
//属性
INSTANCE;
public void sayOK(){
System.out.println("ok,yes");
}
}
}
单例模式的说明::;;