乐趣区

关于java:每天5分钟创建型模式二

这篇就是设计模式的最初一篇文章了,写的十分简洁,基本上是通过例子来解释模式。尽管并没有很深挖,然而如果能帮到你们了解到是什么这个境地我感觉就够了。

下一个系列的话,大概率是 spring 全家桶这方面的,也有可能是其它方面的。

单例模式

单例模式应该算是最罕用的设计模式了叭,驰名的双重校验也是单例模式的一种实现。所谓单例模式就是用来保障一个对象只能创立一个实例,除此之外,它还提供了对实例的全局拜访形式。

单例模式 UML 类图

单例模式饿汉式

所谓饿汉式,人饿了看到啥都想吃。同样,不论需不需要这个实例,反正我都先给你创立好。

一般实现

public class SingletonHungry {
    
    // 在类加载的时候就曾经创立了惟一的实例
    private static final SingletonHungry instance = new SingletonHungry();
    
    // 保障内部不能调用构造函数
    private SingletonHungry() {}

    // 内部调用这个办法,就返回实例
    public static SingletonHungry getInstance() {return instance;}
    
    // 类中其它办法,尽量是 static
    public static void func(){}
    
}

动态代码块

public class SingletonHungryStatic {
    // 其实就是把 new 的局部移到了动态代码块中
    private static SingletonHungryStatic instance = null;
    static {instance = new SingletonHungryStatic();
    }

    private SingletonHungryStatic() {}

    public static SingletonHungryStatic getInstance() {return instance;}

    // 类中其它办法,尽量是 static
    public static void func(){}
}

单例模式懒汉式

所谓懒汉,就是要不是有人督促,就不肯去劳动。同理,只有你找我要这个是,才创立进去。

一般实现

public class SingletonLazy {
    //volatile 之前曾经讲过,避免指令的重排序,这个 volatile 是不能省略的
    private static volatile SingletonLazy instance = null;
    private SingletonLazy(){}

    public static SingletonLazy getInstance() throws Exception {if(instance == null) {synchronized (SingletonLazy.class) {if(instance == null) {instance = new SingletonLazy();
                }
            }
        }
        return instance;
    }
}

动态外部类

public class SingletonLazyStatic {
    
    /**
     * 动态外部类注意事项
     *  1. 类加载的时,动态外部类不会随着加载
     *  2. 动态外部类只会初始化一次
     *  3. 线程平安的
     */
    
    private static class StaticClassInstance{private static final SingletonLazyStatic INSTACE = new SingletonLazyStatic();
    }
    private SingletonLazyStatic() {}
    
    public static SingletonLazyStatic getInstance() {return StaticClassInstance.INSTACE;}
}

其实还有一种更为优雅的实现形式,那就是应用枚举,不过之前看那些文章如同都说什么少用,所以本文就不粘进去给各位减少学习老本了。

Client

public class Client {public static void main(String[] args) throws Exception {//        hungry();
//        hungryStatic();
//        lazy();
        lazyStatic();}

    public static void lazyStatic() {SingletonLazyStatic instance = SingletonLazyStatic.getInstance();
        SingletonLazyStatic instance1 = SingletonLazyStatic.getInstance();
        System.out.println(instance);
        System.out.println(instance1);
    }
    
    // 上面 3 中和下面实现是相似的,只须要更换类名
    public static void lazy() throws Exception {}

    public static void hungry() {}

    public static void hungryStatic() {}

}

原型模式

原型模式听起来高大上,其实就是一种克隆对象的办法。

说到克隆不得不简略说下浅拷贝和深拷贝,浅拷贝就是指两个指针指向了同一个对象,原对象和拷贝对象只有有一个批改,另外一个也随着批改。深拷贝是指,从新创立了一个和原对象截然不同内容的拷贝对象,两者是独立的。根本数据类型是不参加拷贝过程的

Prototype: 形象原型类,申明了 clone 办法的接口或者基类,其中 clone 办法必须由派生对象实现。

Concrete Prototype: 具体实现类,次要是用于实现或扩大 clone 办法的类。

原型模式 UML 类图

原型模式

Prototype

public abstract class PrototypePhone implements Cloneable {
    private String cpu;
    private int price;

    @Override
    public  Object clone() throws CloneNotSupportedException {return super.clone();
    }
    
    // 省略构造函数,get,set 办法

}

Concrete Prototype

public class ConcretePrototypeOnePlus extends PrototypePhone {public ConcretePrototypeOnePlus(String cpu, int price) {super(cpu, price);
        System.out.println("调用了构造函数");
    }

    @Override
    public Object clone() throws CloneNotSupportedException {return super.clone();
    }
}

Client

public class Client {public static void main(String[] args) throws CloneNotSupportedException {PrototypePhone phone = new ConcretePrototypeOnePlus("865", 3999);
        System.out.println("原型:" + phone);
        for (int i = 0; i < 100; i++) {System.out.println("生产第" + (i + 1) + "台手机:" + phone.clone());
        }
    }
}

运行的话就会发现构建的手机只通过了一次构造函数,其它的应用 phone.clone() 也能同样结构出手机实例对象。

退出移动版